<commit_before>
# JSON Handling

## Add the JSON support module(s)

http4s-core does not include JSON support, but integration with some
popular Scala JSON libraries are supported as modules.

### Circe

The http4s team recommends circe.  Only http4s-circe is required for
basic interop with circe, but to follow this tutorial, install all three:

```scala
val http4sVersion = "@{version.http4s.doc}"

libraryDependencies ++= Seq(
  "org.http4s" %% "http4s-circe" % http4sVersion,
  // Optional for auto-derivation of JSON codecs
  "io.circe" %% "circe-generic" % "@{version.circe}",
  // Optional for string interpolation to JSON model
  "io.circe" %% "circe-literal" % "@{version.circe}"
)

addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
```

If you're in a REPL, we also need a runtime:

```scala mdoc:silent:nest
import cats.effect.unsafe.IORuntime
implicit val runtime: IORuntime = cats.effect.unsafe.IORuntime.global
```

## Sending Raw JSON

Let's create a function to produce a simple JSON greeting with circe. First, the imports:

```scala mdoc:silent
import cats.effect._
import io.circe._
import io.circe.literal._
import org.http4s._
import org.http4s.dsl.io._
import org.http4s.implicits._
```

Then the actual code:

```scala mdoc
def hello(name: String): Json =
  json"""{"hello": $name}"""

val greeting = hello("world")
```

We now have a JSON value, but we don't have enough to render it:

```scala mdoc:fail
Ok(greeting).unsafeRunSync()
```

To encode a Scala value of type `A` into an entity, we need an
`EntityEncoder[A]` in scope.  The http4s-circe module includes a
`org.http4s.circe` object, which gives us exactly this for an
`io.circe.Json` value:

```scala mdoc:silent
import org.http4s.circe._
```

```scala mdoc
Ok(greeting).unsafeRunSync()
```

The same `EntityEncoder[Json]` we use on server responses is also
useful on client requests:

```scala mdoc:silent
import org.http4s.client.dsl.io._
```

```scala mdoc
POST(json"""{"name": "Alice"}""", uri"/hello")
```

## Encoding case classes as JSON

These JSON literals are nice, but in real apps, we prefer to operate
on case classes and use JSON as a serialization format near the edge
of the world.

Let's define a couple case classes:

```scala mdoc:silent
case class Hello(name: String)
case class User(name: String)
```

To transform a value of type `A` into `Json`, circe uses an
`io.circe.Encoder[A]`.  With circe's syntax, we can convert any value
to JSON as long as an implicit `Encoder` is in scope:

```scala mdoc:silent
import io.circe.syntax._
```

```scala mdoc:fail
Hello("Alice").asJson
```

Oops!  We haven't told Circe how we want to encode our case class.
Let's provide an encoder:

```scala mdoc
implicit val HelloEncoder: Encoder[Hello] =<commit_msg>Removing failing example in json.md<commit_after>
# JSON Handling

## Add the JSON support module(s)

http4s-core does not include JSON support, but integration with some
popular Scala JSON libraries are supported as modules.

### Circe

The http4s team recommends circe.  Only http4s-circe is required for
basic interop with circe, but to follow this tutorial, install all three:

```scala
val http4sVersion = "@{version.http4s.doc}"

libraryDependencies ++= Seq(
  "org.http4s" %% "http4s-circe" % http4sVersion,
  // Optional for auto-derivation of JSON codecs
  "io.circe" %% "circe-generic" % "@{version.circe}",
  // Optional for string interpolation to JSON model
  "io.circe" %% "circe-literal" % "@{version.circe}"
)

addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
```

If you're in a REPL, we also need a runtime:

```scala mdoc:silent:nest
import cats.effect.unsafe.IORuntime
implicit val runtime: IORuntime = cats.effect.unsafe.IORuntime.global
```

## Sending Raw JSON

Let's create a function to produce a simple JSON greeting with circe. First, the imports:

```scala mdoc:silent
import cats.effect._
import io.circe._
import io.circe.literal._
import org.http4s._
import org.http4s.dsl.io._
import org.http4s.implicits._
```

Then the actual code:

```scala mdoc
def hello(name: String): Json =
  json"""{"hello": $name}"""

val greeting = hello("world")
```

We now have a JSON value, but we don't have enough to render it:

```scala mdoc:fail
Ok(greeting).unsafeRunSync()
```

To encode a Scala value of type `A` into an entity, we need an
`EntityEncoder[A]` in scope.  The http4s-circe module includes a
`org.http4s.circe` object, which gives us exactly this for an
`io.circe.Json` value:

```scala mdoc:silent
import org.http4s.circe._
```

```scala mdoc
Ok(greeting).unsafeRunSync()
```

The same `EntityEncoder[Json]` we use on server responses is also
useful on client requests:

```scala mdoc:silent
import org.http4s.client.dsl.io._
```

```scala mdoc
POST(json"""{"name": "Alice"}""", uri"/hello")
```

## Encoding case classes as JSON

These JSON literals are nice, but in real apps, we prefer to operate
on case classes and use JSON as a serialization format near the edge
of the world.

Let's define a couple case classes:

```scala mdoc:silent
case class Hello(name: String)
case class User(name: String)
```

To transform a value of type `A` into `Json`, circe uses an
`io.circe.Encoder[A]`.  With circe's syntax, we can convert any value
to JSON as long as an implicit `Encoder` is in scope:

```scala mdoc
import io.circe.syntax._

implicit val HelloEncoder: Encoder[Hello] =
{'fraction_non_alphanumeric': 0.12240014724829744, 'fraction_numerical': 0.006626173384870237, 'mean_word_length': 4.631088082901554, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1044538', 'n_tokens_mistral': 1911, 'n_tokens_neox': 1781, 'n_words': 662}