0Pricing
Scala for Backend Engineering & Functional Programming · Leçon

Points de terminaison JSON

Combinez http4s et Circe.

Points de terminaison JSON est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Scala for Backend Engineering & Functional Programming, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.

JSON avec circe

http4s intègre JSON grâce au module http4s-circe, qui relie les codecs circe à EntityDecoder et EntityEncoder. circe est la bibliothèque JSON fonctionnelle de référence pour Scala.

Vous définissez des instances Encoder et Decoder pour vos types, puis vous laissez http4s gérer le format d’échange.

// build.sbt
// "org.http4s" %% "http4s-circe" % http4sV
// "io.circe"   %% "circe-generic" % circeV

Dériver les codecs

Avec circe-generic, vous dérivez automatiquement les codecs à l’aide de deriveEncoder/deriveDecoder ou de l’annotation @JsonCodec. Ils associent les champs des classes de cas aux clés JSON portant le même nom.

La dérivation nécessite récursivement des codecs pour chaque type de champ.

import io.circe.generic.semiauto._

case class User(id: Int, name: String)
implicit val enc = deriveEncoder[User]
implicit val dec = deriveDecoder[User]

EntityEncoder avec circe

L’import org.http4s.circe.CirceEntityEncoder._ fournit implicitement un EntityEncoder[F, A] pour tout A possédant un Encoder circe. Ensuite, Ok(user) sérialise la valeur en JSON avec application/json.

Aucune conversion manuelle en Json n’est nécessaire dans les gestionnaires.

import org.http4s.circe.CirceEntityEncoder._

HttpRoutes.of[IO] {
  case GET -> Root / "me" => Ok(User(1, "Ada"))
}

EntityDecoder avec circe

Le fonctionnement inverse : org.http4s.circe.CirceEntityDecoder._ fournit un EntityDecoder[F, A] pour tout A possédant un Decoder circe. Ensuite, req.as[User] analyse le corps JSON.

Les deux imports sont regroupés dans CirceEntityCodec._.

import org.http4s.circe.CirceEntityDecoder._

case req @ POST -> Root / "users" =>
  req.as[User].flatMap(u => Created(u))

Un POST JSON complet

En combinant le décodage et l’encodage, vous obtenez un point de terminaison de création clair : analysez le JSON reçu vers un type métier, exécutez la logique métier, puis encodez le résultat à nouveau en JSON.

Les échecs de décodage apparaissent sous forme de 422 ou de 400 via le décodeur circe.

import org.http4s.circe.CirceEntityCodec._

case req @ POST -> Root / "users" =>
  for {
    in  <- req.as[User]
    out <- store.create(in)
    res <- Created(out)
  } yield res

L’interpolateur json

Pour du JSON ponctuel, l’interpolateur de chaînes json de circe, issu de io.circe.literal, construit directement une valeur Json avec des valeurs Scala interpolées.

C’est utile pour de petites réponses ou des données de test sans classe de cas.

import io.circe.literal._

val body = json"""{ "status": "ok", "count": 3 }"""
Ok(body)

Noms de champs personnalisés

Lorsque les clés JSON diffèrent des noms de champs Scala, dérivez-les avec une Configuration de circe-generic-extras, par exemple snake_case, ou écrivez le codec manuellement avec forProduct2.

Vous découplez ainsi le contrat de votre API des conventions de nommage internes.

import io.circe.Encoder

implicit val e: Encoder[User] =
  Encoder.forProduct2("user_id", "full_name")(u => (u.id, u.name))

Encoder des listes

circe fournit automatiquement des codecs pour List, Vector, Option et Map dès que le codec des éléments existe. Le renvoi d’une collection fonctionne donc directement.

Une liste vide est encodée en [], et None en clé absente ou en null.

import org.http4s.circe.CirceEntityEncoder._

case GET -> Root / "users" =>
  store.all.flatMap(us => Ok(us)) // List[User] -> JSON array

Valider le JSON décodé

Le décodage vous fournit une valeur syntaxiquement valide ; la validation sémantique vous incombe. Effectuez les vérifications après as et interrompez le traitement avec BadRequest lorsque la valeur est invalide.

Conservez les invariants métier dans des constructeurs intelligents renvoyant Either, pour plus de clarté.

req.as[User].flatMap { u =>
  if (u.name.nonEmpty) Created(u)
  else BadRequest("name required")
}

Réponses d’erreur en JSON

Renvoyez les erreurs structurées en JSON afin que les clients puissent les analyser. Définissez une classe de cas représentant l’erreur, avec un encodeur circe, puis transmettez-la au constructeur d’état approprié.

Des structures d’erreur cohérentes rendent les API beaucoup plus faciles à utiliser.

case class ApiError(code: String, message: String)
implicit val e = deriveEncoder[ApiError]

BadRequest(ApiError("E_NAME", "name required"))

JSON diffusé en flux

Pour les grandes collections, vous pouvez diffuser le JSON au lieu de le mettre en mémoire tampon. jsonEncoderOf associé à un Stream[F, A] fs2 émet progressivement un tableau JSON.

La mémoire reste ainsi stable pour les grands ensembles de résultats, grâce à la contre-pression de fs2.

import org.http4s.circe.streamJsonArrayEncoder

case GET -> Root / "feed" =>
  Ok(store.streamAll) // fs2.Stream[IO, Event]

Vérification rapide

Rappelez-vous quel import permet de décoder un corps JSON en classe de cas.

Récapitulatif

Vous avez intégré JSON avec http4s-circe : dérivé les codecs, importé CirceEntityCodec et utilisé Ok(value) / req.as[A] pour gérer entièrement les entrées et sorties JSON.

Vous avez traité les listes, les noms de champs personnalisés, les erreurs JSON structurées et même les tableaux diffusés en flux pour les grandes charges utiles.

Questions Fréquemment Posées

La leçon « Points de terminaison JSON » est-elle gratuite ?

Oui — le texte complet de « Points de terminaison JSON » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Scala for Backend Engineering & Functional Programming, passe à CoddyKit PRO. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Points de terminaison JSON » ?

Combinez http4s et Circe. Tu pratiques Scala for Backend Engineering & Functional Programming avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Scala for Backend Engineering & Functional Programming ?

Aucune expérience préalable n'est requise. Scala for Backend Engineering & Functional Programming sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Points de terminaison JSON » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Scala for Backend Engineering & Functional Programming ?

Oui. Chaque leçon Scala for Backend Engineering & Functional Programming inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Routes et HttpRoutes
  2. Requêtes et réponses
  3. Points de terminaison JSON
  4. Servir l’application
← Retour à Scala for Backend Engineering & Functional Programming