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

Декодирование в классы вариантов

Отображайте JSON на свои типы.

Урок 2 из 413 шагов

«Декодирование в классы вариантов» — бесплатный урок 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 — локальная установка не требуется.

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

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