0Pricing
Scala for Backend Engineering & Functional Programming · Урок

Разбор JSON

Преобразуйте текст в значения JSON.

«Разбор JSON» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.

Зачем нужен Circe?

Circe — популярная библиотека JSON для Scala, построенная на функциональной экосистеме cats.

Она отдаёт предпочтение типобезопасности и неизменяемости: синтаксический разбор возвращает Either, а не выбрасывает исключение, а декодирование создаёт типизированные значения вместо нетипизированных отображений.

В этом уроке рассматривается преобразование необработанного текста JSON в модель Json библиотеки Circe.

Добавление зависимости

Circe поставляется в виде нескольких модулей. Для разбора и основной модели нужны circe-core и circe-parser.

Модуль circe-generic добавляет автоматический вывод кодеков, который рассматривается в следующих уроках.

libraryDependencies ++= Seq(
  "io.circe" %% "circe-core" % "0.14.6",
  "io.circe" %% "circe-parser" % "0.14.6"
)

Функция parse

Точка входа для чтения JSON — io.circe.parser.parse.

Она принимает String и возвращает Either[ParsingFailure, Json]. Левая сторона содержит синтаксические ошибки, а правая — разобранное дерево.

import io.circe.parser._

val result = parse("{\"name\": \"Ada\", \"age\": 36}")
// result: Either[ParsingFailure, Json]

Обработка ошибок разбора

Поскольку parse возвращает Either, Вы обрабатываете ошибки явно с помощью сопоставления с образцом или комбинаторов, а не через try/catch.

ParsingFailure содержит понятное человеку сообщение с описанием синтаксической проблемы.

parse("{ not valid }") match {
  case Right(json) => println(json)
  case Left(err)   => println(s"Failed: ${err.message}")
}

Модель Json

Успешно разобранное значение — это Json, неизменяемое дерево, представляющее один из шести типов JSON: объект, массив, строку, число, логическое значение или null.

Вы можете исследовать его с помощью предикатов, таких как isObject, или свернуть дерево в зависимости от его формы.

val json = parse("[1, 2, 3]").getOrElse(Json.Null)
println(json.isArray)   // true
println(json.isObject)  // false

Навигация с помощью курсора

Чтобы читать вложенные данные, вызовите .hcursor для значения Json. HCursor — это зиппер, позволяющий перемещаться по дереву.

Используйте downField, чтобы перейти к ключу объекта.

val json = parse("{\"user\": {\"name\": \"Ada\"}}").toOption.get
val cursor = json.hcursor
val name = cursor.downField("user").downField("name").as[String]
// name: Either[DecodingFailure, String] = Right(Ada)

Извлечение значений с помощью as

После позиционирования .as[A] пытается декодировать выбранное значение в тип A.

Он возвращает Either[DecodingFailure, A], поэтому несоответствие типов представляется как значение, а не как исключение.

val json = parse("{\"age\": 36}").toOption.get
val age = json.hcursor.downField("age").as[Int]
println(age)  // Right(36)

parse и decode

Используйте parse, если хотите вручную исследовать необработанное дерево Json.

Используйте decode[A], если хотите за один шаг перейти от String к типизированному значению A. Эта операция объединяет разбор и декодирование.

import io.circe.parser.decode

val n: Either[io.circe.Error, Int] =
  decode[Int]("42")
println(n)  // Right(42)

Необязательные поля

В реальном JSON ключи часто отсутствуют. Метод курсора get[A] для указанного поля завершается ошибкой, если поле отсутствует, а getOrElse подставляет значение по умолчанию.

Декодирование в Option[A] трактует отсутствующее поле или поле со значением null как None.

val json = parse("{\"name\": \"Ada\"}").toOption.get
val nick = json.hcursor.get[Option[String]]("nickname")
println(nick)  // Right(None)

Разбор массивов

Вы можете напрямую декодировать массив JSON в коллекцию Scala, запросив List[A] или Vector[A].

Circe преобразует каждый элемент и прекращает обработку с ошибкой DecodingFailure, если тип какого-либо элемента неверен.

import io.circe.parser.decode

val xs = decode[List[Int]]("[1, 2, 3]")
println(xs)  // Right(List(1, 2, 3))

Форматированный вывод

Любое значение Json можно снова вывести в текст с помощью .noSpaces для компактного вывода или .spaces2 для вывода с отступами.

Это позволяет преобразовать разобранные данные обратно и удобно для журналирования или отладки.

val json = parse("{\"a\":1,\"b\":2}").toOption.get
println(json.noSpaces)
println(json.spaces2)

Быстрая проверка

Проверьте, насколько хорошо Вы поняли разбор Circe.

Итоги

Вы научились преобразовывать текст JSON в модель Circe. parse возвращает Either[ParsingFailure, Json], а decode[A] сразу создаёт типизированное значение.

HCursor перемещается с помощью downField, а .as[A] извлекает типизированные значения. Ошибки представлены значениями, а не исключениями.

Часто задаваемые вопросы

Урок «Разбор JSON» бесплатный?

Да — полный текст урока «Разбор JSON» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.

Чему я научусь в уроке «Разбор JSON»?

Преобразуйте текст в значения JSON. Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?

Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Разбор JSON»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?

Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Разбор JSON
  2. Декодирование в классы вариантов
  3. Кодирование в JSON
  4. Пользовательские кодеки
← Назад к Scala for Backend Engineering & Functional Programming