=== Request Body

Raw `request body` is available via javadoc:Context[body] method:

.Java
[source,java,role="primary"]
----
{
  post("/string", ctx -> {
    String body = ctx.body().value();        // <1>
    ...
  });
  
  post("/bytes", ctx -> {
    byte[] body = ctx.body().bytes();        // <2>
    ...
  });
  
  post("/stream", ctx -> {
    InputStream body = ctx.body().stream();  // <3>
    ...
  });
}
----

.Kotlin
[source,kotlin,role="secondary"]
----
{
  post("/string") {
    val body = ctx.body().value()   // <1>
    ...
  }
  
  post("/bytes") {
    val body = ctx.body().bytes()   // <2>
    ...
  }
  
  post("/stream") {
    val body = ctx.body().stream()  // <3>
    ...
  }
}
----

<1> `HTTP Body` as `String`
<2> `HTTP Body` as `byte array`
<3> `HTTP Body` as `InputStream`

This give us the `raw body`.

==== Message Decoder

Request body parsing is achieved using the javadoc:MessageDecoder[] functional interface.

[source, java]
----
public interface MessageDecoder {

  <T> T decode(Context ctx, Type type) throws Exception;
}
----

javadoc:MessageDecoder[] has a single `decode` method that takes two input arguments: `(context, type)`
and returns a single result of the given type.

.JSON example:
[source, java, role="primary"]
----
{
  FavoriteJson lib = new FavoriteJson();           // <1>

  decoder(MediaType.json, (ctx, type) -> {          // <2>

    byte[] body = ctx.body().bytes();              // <3>

    return lib.fromJson(body, type);               // <4>
  });

  post("/", ctx -> {
    MyObject myObject = ctx.body(MyObject.class);  // <5>
  });
}
----

.Kotlin
[source, kotlin, role="secondary"]
----
{
  val lib = FavoriteJson()                 // <1>

  decoder(MediaType.json) { ctx, type ->    // <2>

    val body = ctx.body().bytes()          // <3>

    lib.fromJson(body, type)               // <4>
  }

  post("/") {
    val myObject = ctx.body<MyObject>()    // <5>
  }
}
----

<1> Choose your favorite `json` library
<2> Check if the `Content-Type` header matches `application/json`
<3> Read the body as `byte[]`
<4> Parse the `body` and use the requested type
<5> Route handler now call the `body(Type)` function to trigger the decoder function

[TIP]
====

Jooby comes with a `json` decoder built on top of https://github.com/FasterXML/jackson-databind[Jackson]:

[dependency, artifactId="jooby-jackson"]
.

====

=== Response Body

Response body is generated from `handler` function:

.Response body
[source, java,role="primary"]
----
{
  get("/", ctx -> {
    ctx.setResponseCode(200);                  // <1>

    ctx.setResponseType(MediaType.text);        // <2>

    ctx.setResponseHeader("Date", new Date());  // <3>

    return "Response";                          // <4>
  });
}
----

.Kotlin
[source, kotlin,role="secondary"]
----
{
  get("/") {
    ctx.responseCode = 200                 // <1>

    ctx.responseType = MediaType.text      // <2>

    ctx.setResponseHeader("Date", Date())  // <3>

    "Response"                             // <4>
  }
}
----

<1> Set `status code` to `OK(200)`. This is the default `status code`
<2> Set `content-type` to `text/plain`. This is the default `content-type`
<3> Set the `date` header
<4> Send a `Response` string to the client

==== Message Encoder

Response enconding is achieved using the javadoc:MessageEncoder[] functional interface.

[source, java]
----
public interface MessageEncoder {

  byte[] encode(@Nonnull Context ctx, @Nonnull Object value) throws Exception;
}
----

MessageEncoder has a single `encode` method that accepts two input arguments: `(context, result)` and 
produces a result.

.JSON example:
[source, java, role="primary"]
----
{
  FavoriteJson lib = new FavoriteJson();           // <1>

  encoder(MediaType.json, (ctx, result) -> {      // <2>

    String json = lib.toJson(result);              // <3>

    ctx.setDefaultResponseType(MediaType.json);    // <4>

    return json;                                   // <5>
  });

  get("/item", ctx -> {
    MyObject myObject = ...;
    return myObject;                               // <6>
  });
}
----

.Kotlin
[source, kotlin, role="secondary"]
----
{
  val lib = FavoriteJson()                         // <1>

  encoder(MediaType.json) { ctx, result ->        // <2>

    val json = lib.toJson(result)                  // <3>

    ctx.defaultResponseType = MediaType.json       // <4>

    json                                           // <5>
  }

  get("/item") {
    val myObject = ...;
    myObject                                       // <6>
  }
}
----

<1> Choose your favorite `json` library
<2> Check if the `Accept` header matches `application/json`
<3> Convert `result` to `JSON`
<4> Set default `Content-Type` to `application/json`
<5> Produces JSON response
<6> Route handler returns a user defined type

[TIP]
====

Jooby comes with a `json` encoder built on top of https://github.com/FasterXML/jackson-databind[Jackson]:

[dependency, artifactId="jooby-jackson"]
.

====
