Marshalling Directives
Marshalling directives handle the conversion between HTTP request/response bodies and Scala types. http4s-stir uses the http4s EntityDecoder and EntityEncoder type classes under the hood, making it compatible with any http4s marshalling ecosystem including Circe, jsoniter, and others.
entity
Unmarshals the request body to the given type T. Requires an implicit EntityDecoder[IO, T] in scope. If unmarshalling fails, the request is rejected with an EntityRejection.
import org.http4s.EntityDecoder
case class User(name: String, age: Int)
val route: Route = path("users") {
post {
entity(as[User]) { user =>
complete(s"Created user: ${user.name}")
}
}
}
as
A helper that returns the in-scope EntityDecoder[IO, T] for the given type. It is used as the argument to entity:
entity(as[String]) { body =>
complete(s"Body: $body")
}
handleWith
Combines unmarshalling the request body, applying a function, and marshalling the result into a single directive. Requires both an implicit EntityDecoder[IO, A] for the input type and a ToResponseMarshaller[B] for the output type.
case class Request(query: String)
case class Response(result: String)
val process: Request => Response = req => Response(s"Result for: ${req.query}")
val route: Route = path("process") {
post {
handleWith(process)
}
}
Circe Integration
For JSON marshalling with Circe, import the http4s Circe entity codecs. Any type with a Circe Encoder or Decoder in scope will automatically gain EntityEncoder and EntityDecoder instances.
import io.circe.generic.auto._
import org.http4s.circe.CirceEntityEncoder._
import org.http4s.circe.CirceEntityDecoder._
case class Item(name: String, price: Double)
val route: Route = path("items") {
post {
entity(as[Item]) { item =>
complete(Item(item.name, item.price * 1.1))
}
}
}
ToResponseMarshaller
ToResponseMarshaller[T] is a type class that defines how a value of type T is converted into an IO[Response[IO]]. It is used by the complete directive to produce HTTP responses. The following implicit instances are provided:
EntityEncoder[IO, E]-- any type with an http4sEntityEncodercan be completed directly. The response uses status200 OK.(Status, E)-- a tuple of HTTP status and entity produces a response with the given status.(Status, Headers)-- a tuple of status and headers produces a response with no body.(Status, Headers, E)-- a tuple of status, headers, and entity produces a fully specified response.Status-- a bare status code produces an empty-body response.IO[E]-- anIOwrapping any marshallable type is flatMapped to produce the response.Response[IO]-- a raw http4sResponse[IO]is passed through directly.
import org.http4s.Status
import org.http4s.Headers
import org.http4s.headers.`Content-Type`
import org.http4s.MediaType
// Complete with just a body (200 OK)
complete("Hello, world!")
// Complete with a status code and body
complete((Status.Created, """{"id": 1}"""))
// Complete with status, headers, and body
complete((Status.Ok, Headers(`Content-Type`(MediaType.application.json)), """{"ok": true}"""))
// Complete with just a status code
complete(Status.NoContent)
// Complete with an IO value
complete(IO.pure("Async result"))
ToResponseMarshallable
ToResponseMarshallable is a wrapper that pairs a value with its ToResponseMarshaller instance. The complete directive accepts ToResponseMarshallable, and any type T with a ToResponseMarshaller[T] in scope is implicitly converted to ToResponseMarshallable.
instanceOf
A helper that summons the implicit ToResponseMarshaller[T] for a given type. Useful when you need to pass a marshaller explicitly.
val stringMarshaller: ToResponseMarshaller[String] = instanceOf[String]
Unmarshaller
Unmarshaller[A, B] is a type class for converting a value of type A into IO[B]. It is used internally by the parameter, form field, and path directives for type conversion from String values.
Key operations:
map[C](f: B => C)-- transforms the output type.flatMap[C](f: B => IO[C])-- chains with an effectful transformation.andThen[C](other: Unmarshaller[B, C])-- composes two unmarshallers sequentially.withDefaultValue[BB >: B](default: BB)-- provides a fallback when no content is available.recover[C >: B](pf: PartialFunction[Throwable, C])-- handles errors with a partial function.
Built-in unmarshallers are provided for standard types such as String, Int, Long, Double, Float, Short, Byte, Boolean, and BigDecimal.