Endpoint JSON
Combini http4s con Circe.
Endpoint JSON è una lezione Scala for Backend Engineering & Functional Programming gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Scala for Backend Engineering & Functional Programming, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.
JSON con circe
http4s integra JSON tramite il modulo http4s-circe, che collega i codec di circe a EntityDecoder e EntityEncoder. circe è di fatto la libreria JSON funzionale di riferimento per Scala.
Si definiscono istanze di Encoder e Decoder per i propri tipi e si lascia che http4s gestisca il formato sul filo.
// build.sbt
// "org.http4s" %% "http4s-circe" % http4sV
// "io.circe" %% "circe-generic" % circeVDerivazione dei codec
Con circe-generic si derivano automaticamente i codec usando deriveEncoder/deriveDecoder oppure l’annotazione @JsonCodec. I campi delle case class vengono associati alle chiavi JSON in base al nome.
La derivazione richiede ricorsivamente codec per il tipo di ogni campo.
import io.circe.generic.semiauto._
case class User(id: Int, name: String)
implicit val enc = deriveEncoder[User]
implicit val dec = deriveDecoder[User]EntityEncoder da circe
L’import org.http4s.circe.CirceEntityEncoder._ fornisce un EntityEncoder[F, A] implicito per ogni A che dispone di un Encoder di circe. In questo modo Ok(user) viene serializzato in JSON con application/json.
Nei gestori non è necessaria alcuna conversione manuale in Json.
import org.http4s.circe.CirceEntityEncoder._
HttpRoutes.of[IO] {
case GET -> Root / "me" => Ok(User(1, "Ada"))
}EntityDecoder da circe
È il procedimento inverso: org.http4s.circe.CirceEntityDecoder._ fornisce un EntityDecoder[F, A] per ogni A che dispone di un Decoder di circe. Quindi req.as[User] analizza il body JSON.
Entrambi gli import sono disponibili insieme tramite CirceEntityCodec._.
import org.http4s.circe.CirceEntityDecoder._
case req @ POST -> Root / "users" =>
req.as[User].flatMap(u => Created(u))Un POST JSON completo
Combinare decoding ed encoding permette di creare un endpoint di creazione chiaro: si analizza il JSON ricevuto in un tipo di dominio, si esegue la logica applicativa e poi si codifica nuovamente il risultato come JSON.
Gli errori di decoding vengono restituiti come 422 o 400 tramite il decoder di circe.
import org.http4s.circe.CirceEntityCodec._
case req @ POST -> Root / "users" =>
for {
in <- req.as[User]
out <- store.create(in)
res <- Created(out)
} yield resL’interpolatore json
Per JSON ad hoc, l’interpolatore di stringhe json di circe, proveniente da io.circe.literal, costruisce direttamente un valore Json con valori Scala interpolati.
È utile per piccole risposte o fixture di test quando non si dispone di una case class.
import io.circe.literal._
val body = json"""{ "status": "ok", "count": 3 }"""
Ok(body)Nomi dei campi personalizzati
Quando le chiavi JSON differiscono dai nomi dei campi Scala, si può derivare il codec con una Configuration di circe-generic-extras, ad esempio snake_case, oppure scriverlo manualmente usando forProduct2.
In questo modo il contratto dell’API resta indipendente dalla nomenclatura interna.
import io.circe.Encoder
implicit val e: Encoder[User] =
Encoder.forProduct2("user_id", "full_name")(u => (u.id, u.name))Codifica delle liste
circe fornisce automaticamente codec per List, Vector, Option e Map non appena esiste il codec degli elementi. Restituire una collezione funziona quindi senza configurazioni aggiuntive.
Una lista vuota viene codificata come [] e None come chiave assente oppure null.
import org.http4s.circe.CirceEntityEncoder._
case GET -> Root / "users" =>
store.all.flatMap(us => Ok(us)) // List[User] -> JSON arrayValidazione del JSON decodificato
Il decoding restituisce un valore sintatticamente valido; la validazione semantica spetta a Lei. Esegua i controlli dopo as e interrompa il flusso con BadRequest quando il valore non è valido.
Mantenga gli invarianti del dominio in smart constructor che restituiscono Either, per maggiore chiarezza.
req.as[User].flatMap { u =>
if (u.name.nonEmpty) Created(u)
else BadRequest("name required")
}Risposte di errore come JSON
Restituisca gli errori strutturati come JSON, così i client possono analizzarli. Definisca una case class per l’errore con un encoder di circe e la passi al builder dello status appropriato.
Strutture di errore coerenti rendono le API molto più semplici da utilizzare.
case class ApiError(code: String, message: String)
implicit val e = deriveEncoder[ApiError]
BadRequest(ApiError("E_NAME", "name required"))JSON in streaming
Per collezioni di grandi dimensioni è possibile trasmettere il JSON in streaming invece di inserirlo tutto in memoria. jsonEncoderOf insieme a uno Stream[F, A] di fs2 emette progressivamente un array JSON.
In questo modo la memoria utilizzata rimane costante anche per grandi insiemi di risultati, sfruttando il back-pressure di fs2.
import org.http4s.circe.streamJsonArrayEncoder
case GET -> Root / "feed" =>
Ok(store.streamAll) // fs2.Stream[IO, Event]Verifica rapida
Ricordi quale import abilita il decoding di un body JSON in una case class.
Riepilogo
Ha configurato JSON con http4s-circe: ha derivato i codec, importato CirceEntityCodec e usato Ok(value) / req.as[A] per l’I/O JSON completo.
Ha gestito liste, nomi di campo personalizzati, errori JSON strutturati e persino array in streaming per payload di grandi dimensioni.
Domande Frequenti
La lezione «Endpoint JSON» è gratuita?
Sì — il testo completo di «Endpoint JSON» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Scala for Backend Engineering & Functional Programming, passa a CoddyKit PRO. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.
Cosa imparerò in «Endpoint JSON»?
Combini http4s con Circe. Eserciti Scala for Backend Engineering & Functional Programming con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Scala for Backend Engineering & Functional Programming?
Non è richiesta alcuna esperienza precedente. Scala for Backend Engineering & Functional Programming su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Endpoint JSON»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Scala for Backend Engineering & Functional Programming?
Sì. Ogni lezione Scala for Backend Engineering & Functional Programming include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.