Декодирование в классы вариантов
Отображайте JSON на свои типы.
«Декодирование в классы вариантов» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Декодеры сопоставляют JSON с типами
Decoder[A] умеет преобразовывать значение Json в тип Scala A.
Circe изначально предоставляет декодеры для примитивов и коллекций, а также умеет автоматически создавать декодеры для Ваших собственных классов-образцов.
Целевой класс-образец
Предположим, Ваш API возвращает записи пользователей. Опишите их структуру классом-образцом, имена полей которого совпадают с ключами JSON.
Именно совпадение имён позволяет Circe вывести декодер без ручного связывания.
case class User(name: String, age: Int, admin: Boolean)Автоматический вывод
Импортируйте io.circe.generic.auto._, и Circe неявно выведет Decoder[User] по мере необходимости.
После этого можно вызвать decode[User] без дополнительного шаблонного кода.
import io.circe.generic.auto._
import io.circe.parser.decode
val json = "{\"name\":\"Ada\",\"age\":36,\"admin\":true}"
val user = decode[User](json)
println(user) // Right(User(Ada,36,true))Полуавтоматический вывод
Для ускорения компиляции и явного контроля используйте io.circe.generic.semiauto.deriveDecoder.
Определите декодер один раз, обычно в сопутствующем объекте, и повторно используйте этот единственный экземпляр везде.
import io.circe.Decoder
import io.circe.generic.semiauto._
object User {
implicit val dec: Decoder[User] = deriveDecoder[User]
}Ошибки декодирования
Если обязательное поле отсутствует или имеет неверный тип, декодирование завершается ошибкой DecodingFailure.
Ошибка содержит историю операций курсора, точно указывающую поле, вызвавшее проблему.
val bad = decode[User]("{\"name\":\"Ada\"}")
println(bad)
// Left(DecodingFailure at .age: Missing required field)Необязательные поля в классах
Используйте для поля тип Option[A], если ключ JSON может отсутствовать или иметь значение null.
Circe автоматически декодирует отсутствующий ключ в None, поэтому отдельный декодер только ради необязательности не нужен.
case class Account(id: Long, nickname: Option[String])
val a = decode[Account]("{\"id\":7}")
println(a) // Right(Account(7,None))Значения по умолчанию
Значения полей класса-образца по умолчанию могут заполнять отсутствующие ключи JSON, но только при использовании настроенного вывода, включающего значения по умолчанию.
Модуль circe-generic-extras предоставляет эту возможность через Configuration.default.withDefaults.
import io.circe.generic.extras._
implicit val cfg: Configuration =
Configuration.default.withDefaults
@ConfiguredJsonCodec
case class Settings(theme: String = "dark")Вложенные классы-образцы
Декодирование компонуется: если Circe умеет декодировать тип каждого поля, он сможет декодировать и класс, содержащий другие классы-образцы.
Вывод выполняется рекурсивно автоматически, поэтому одного импорта достаточно для глубоко вложенных структур.
case class Address(city: String)
case class Person(name: String, address: Address)
val p = decode[Person](
"{\"name\":\"Ada\",\"address\":{\"city\":\"London\"}}")
println(p)Переименование полей
Если ключи JSON отличаются от имён Scala, например используют snake_case, применяйте настроенный вывод с Configuration.default.withSnakeCaseMemberNames.
Он сопоставит created_at с полем Scala createdAt без написанного вручную декодера.
import io.circe.generic.extras._
implicit val cfg: Configuration =
Configuration.default.withSnakeCaseMemberNames
@ConfiguredJsonCodec
case class Event(createdAt: String)Накопление ошибок
По умолчанию декодирование останавливается при первой ошибке. decodeAccumulating вместо этого собирает все ошибки в ValidatedNel.
Это полезно при проверке форм, когда нужно сообщить обо всех проблемах сразу.
import io.circe.Decoder
val result = Decoder[User]
.decodeAccumulating(json.hcursor)
// Validated[NonEmptyList[DecodingFailure], User]Выбор стиля вывода
Используйте auto для быстрых прототипов, а semiauto — для производственного кода, где нужны фиксированные экземпляры и более быстрая компиляция.
Обращайтесь к generic-extras, когда нужны переименование, значения по умолчанию или дискриминаторы.
Быстрая проверка
Проверьте, насколько хорошо Вы поняли декодирование в классы-образцы.
Итоги
Decoder[A] преобразует JSON в типизированные значения. Используйте generic.auto или semiauto.deriveDecoder для классов-образцов, имена которых совпадают с ключами.
Отсутствующие ключи декодируют поля Option в None; generic-extras добавляет значения по умолчанию и переименование; decodeAccumulating собирает все ошибки.
Изучай Scala с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 39
- Уроки
- 143
Часто задаваемые вопросы
Урок «Декодирование в классы вариантов» бесплатный?
Да — полный текст урока «Декодирование в классы вариантов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Чему я научусь в уроке «Декодирование в классы вариантов»?
Отображайте JSON на свои типы. Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?
Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Декодирование в классы вариантов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?
Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Разбор JSON
- Декодирование в классы вариантов
- Кодирование в JSON
- Пользовательские кодеки