entity

entity

Signature

Description

Unmarshalls the request entity to the given type and passes it to its inner Route. An unmarshaller returns an Either with Right(value) if successful or Left(exception) for a failure. The entity method will either pass the value to the inner route or map the exception to a akka.http.scaladsl.server.Rejection.

The entity directive works in conjuction with as and akka.http.scaladsl.unmarshalling to convert some serialized "wire format" value into a higher-level object structure. The unmarshalling documentation explains this process in detail. This directive simplifies extraction and error handling to the specified type from the request.

An unmarshaller will return a Left(exception) in the case of an error. This is converted to a akka.http.scaladsl.server.Rejection within the entity directive. The following table lists how exceptions are mapped to rejections:

Left(exception) Rejection
ContentExpected RequestEntityExpectedRejection
UnsupportedContentType UnsupportedRequestContentTypeRejection, which lists the supported types
MaformedContent MalformedRequestContentRejection, with an error message and cause

Examples

The following example uses spray-json to unmarshall a json request into a simple Person class. It utilizes SprayJsonSupport via the PersonJsonSupport object as the in-scope unmarshaller.

case class Person(name: String, favoriteNumber: Int)
object PersonJsonSupport extends DefaultJsonProtocol with SprayJsonSupport {
  implicit val PortofolioFormats = jsonFormat2(Person)
}
import PersonJsonSupport._

val route = post {
  entity(as[Person]) { person =>
    complete(s"Person: ${person.name} - favorite number: ${person.favoriteNumber}")
  }
}

// tests:
Post("/", HttpEntity(`application/json`, """{ "name": "Jane", "favoriteNumber" : 42 }""")) ~>
  route ~> check {
    responseAs[String] shouldEqual "Person: Jane - favorite number: 42"
  }

It is also possible to use the entity directive to obtain raw JsValue ( spray-json ) objects, by simply using as[JsValue], or any other JSON type for which you have marshallers in-scope.

import PersonJsonSupport._

val route = post {
  entity(as[JsValue]) { json =>
    complete(s"Person: ${json.asJsObject.fields("name")} - favorite number: ${json.asJsObject.fields("favoriteNumber")}")
  }
}

// tests:
Post("/", HttpEntity(`application/json`, """{ "name": "Jane", "favoriteNumber" : 42 }""")) ~>
  route ~> check {
    responseAs[String] shouldEqual """Person: "Jane" - favorite number: 42"""
  }

Contents