Scala voor backend-engineering en functioneel programmeren · Les

Aangepaste codecs

Handel lastige structuren af.

Les 4 van 413 stappen

Aangepaste codecs is een gratis Scala voor backend-engineering en functioneel programmeren-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Scala voor backend-engineering en functioneel programmeren. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Scala voor backend-engineering en functioneel programmeren bevat in totaal 4 lessen.

Wanneer je aangepaste codecs nodig hebt

Afleiding dekt het gebruikelijke geval, maar soms komt JSON niet overeen met je case class: bijvoorbeeld door oude veldnamen, gecodeerde enumeraties of indelingen zoals tijdstempels.

Dan schrijf je handmatig een Decoder, een Encoder of beide.

Een decoder vanuit een cursor

De meest expliciete manier om een decoder te bouwen is Decoder.instance, die een HCursor ontvangt.

Je navigeert door velden met downField en as en geeft een Either terug.

import io.circe.Decoder

case class User(name: String, age: Int)
implicit val dec: Decoder[User] = Decoder.instance { c =>
  for {
    n <- c.downField("full_name").as[String]
    a <- c.downField("years").as[Int]
  } yield User(n, a)
}

forProductN-hulpmethoden

Voor eenvoudige toewijzingen is Decoder.forProduct2 beknopter: geef de JSON-sleutels op en geef de constructor door.

Er bestaan hulpmethoden vanaf forProduct1 tot en met veel argumenten.

import io.circe.Decoder

implicit val dec: Decoder[User] =
  Decoder.forProduct2("full_name", "years")(User.apply)

Een encoder met de hand

Spiegel de decoder met Encoder.instance en bouw een Json-object op uit je velden.

Of gebruik Encoder.forProduct2 om in één aanroep terug te mappen naar de gekozen JSON-sleutels.

import io.circe.Encoder

implicit val enc: Encoder[User] =
  Encoder.forProduct2("full_name", "years")(u =>
    (u.name, u.age))

Bestaande codecs transformeren

Je begint zelden vanaf nul. map past de uitvoer van een decoder aan en contramap past de invoer van een encoder aan.

emap werkt zoals map, maar kan mislukken en geeft voor validatie Either[String, A] terug.

import io.circe.Decoder

case class Age(value: Int)
implicit val dec: Decoder[Age] =
  Decoder[Int].emap { i =>
    if (i >= 0) Right(Age(i)) else Left("negative age")
  }

Codecs voor enumeraties

Sealed traits met case objects modelleren enumeraties. Codeer elke variant als een labeltekenreeks en decodeer door die tekenreeks terug te matchen.

emap zet een onbekend label om in een duidelijke decodeerfout.

sealed trait Role
case object Admin extends Role
case object Guest extends Role

implicit val dec: Decoder[Role] = Decoder[String].emap {
  case "admin" => Right(Admin)
  case "guest" => Right(Guest)
  case other   => Left(s"unknown role: $other")
}

De enumeratie terug coderen

Combineer de enumeratiedecoder met een encoder via contramap die elke variant naar zijn label omzet.

De sealed trait wordt nu als een gewone tekenreeks in JSON heen en terug geconverteerd.

import io.circe.Encoder

implicit val enc: Encoder[Role] = Encoder[String].contramap {
  case Admin => "admin"
  case Guest => "guest"
}

Aangepaste codec voor datums

Circe heeft geen ingebouwde java.time-codecs in de kernmodule, dus datums zijn een klassiek geval voor een aangepaste codec.

Decodeer en codeer via de ISO-tekenreeksnotatie.

import java.time.LocalDate
import io.circe.{Decoder, Encoder}

implicit val dec: Decoder[LocalDate] =
  Decoder[String].map(LocalDate.parse)
implicit val enc: Encoder[LocalDate] =
  Encoder[String].contramap(_.toString)

Combineren tot een codec

Wanneer je beide richtingen hebt, combineer je ze tot één Codec[A] met Codec.from(decoder, encoder).

Zo blijft er één impliciete waarde binnen bereik in plaats van twee afzonderlijke.

import io.circe.Codec

implicit val roleCodec: Codec[Role] =
  Codec.from(dec, enc)

Discriminatoren voor ADT's

Voor sealed hiërarchieën met gegevens voegt circe-generic-extras een discriminatorveld toe in plaats van een wrapperobject.

Configureer dit één keer en leid codecs af voor de volledige ADT.

import io.circe.generic.extras._

implicit val cfg: Configuration =
  Configuration.default.withDiscriminator("type")

@ConfiguredJsonCodec sealed trait Shape
@ConfiguredJsonCodec case class Circle(r: Double) extends Shape

Impliciet bereik en prioriteit

Een handgeschreven impliciete codec heeft voorrang op afleiding zolang deze binnen bereik is. Zet deze in het companion object, zodat deze altijd wordt gevonden.

Importeer niet zowel auto._ als een handmatige instantie voor hetzelfde type om dubbelzinnigheid te voorkomen.

Korte controle

Test je begrip van aangepaste codecs.

Samenvatting

Aangepaste codecs verwerken JSON die niet overeenkomt met je typen. Bouw ze met Decoder.instance, forProductN of transformeer bestaande codecs via map, contramap en emap.

Enumeraties en datums zijn veelvoorkomende gevallen; combineer beide richtingen met Codec.from en gebruik discriminatoren voor ADT's.

Gratis beginnen

Leer Scala met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
39
Lessen
143

Veelgestelde vragen

Is de les “Aangepaste codecs” gratis?

Ja — de volledige tekst van “Aangepaste codecs” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Scala voor backend-engineering en functioneel programmeren wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Scala voor backend-engineering en functioneel programmeren bevat in totaal 4 lessen.

Wat leer ik in “Aangepaste codecs”?

Handel lastige structuren af. Je oefent met Scala voor backend-engineering en functioneel programmeren door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Scala voor backend-engineering en functioneel programmeren te beginnen?

Ervaring vooraf is niet nodig. Scala voor backend-engineering en functioneel programmeren op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Aangepaste codecs”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Scala voor backend-engineering en functioneel programmeren?

Ja. Elke les over Scala voor backend-engineering en functioneel programmeren bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. JSON parsen
  2. Decoderen naar case classes
  3. Coderen naar JSON
  4. Aangepaste codecs
← Terug naar Scala voor backend-engineering en functioneel programmeren