entity

Signature

def entity[T](um: FromRequestUnmarshaller[T]): Directive1[T] 

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 RejectionRejection.

The entity directive works in conjunction with as and org.apache.pekko.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 RejectionRejection within the entity directive. The following table lists how exceptions are mapped to rejections:

Left(exception) Rejection
ContentExpected RequestEntityExpectedRejectionRequestEntityExpectedRejection
UnsupportedContentType UnsupportedRequestContentTypeRejectionUnsupportedRequestContentTypeRejection, which lists the supported types
MalformedContent MalformedRequestContentRejectionMalformedRequestContentRejection, with an error message and cause

Examples

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

Scala
sourcecase class Person(name: String, favoriteNumber: Int)
import spray.json.{ DefaultJsonProtocol, RootJsonFormat }

object PersonJsonSupport extends DefaultJsonProtocol with SprayJsonSupport {
  implicit val personFormat: RootJsonFormat[Person] = jsonFormat2(Person.apply)
}
Java
sourcepublic static class Person {
  private final String name;
  private final int favoriteNumber;

  // default constructor required for Jackson
  public Person() {
    this.name = "";
    this.favoriteNumber = 0;
  }

  public Person(String name, int favoriteNumber) {
    this.name = name;
    this.favoriteNumber = favoriteNumber;
  }

  public String getName() {
    return name;
  }

  public int getFavoriteNumber() {
    return favoriteNumber;
  }
}
Scala
sourceimport 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"
}
Java
sourceimport static org.apache.pekko.http.javadsl.server.Directives.complete;
import static org.apache.pekko.http.javadsl.server.Directives.entity;

final Unmarshaller<HttpEntity, Person> unmarshaller = Jackson.unmarshaller(Person.class);

final Route route =
    entity(
        unmarshaller,
        person ->
            complete(
                "Person:"
                    + person.getName()
                    + " - favoriteNumber:"
                    + person.getFavoriteNumber()));

testRoute(route)
    .run(
        HttpRequest.POST("/")
            .withEntity(
                HttpEntities.create(
                    ContentTypes.APPLICATION_JSON,
                    "{\"name\":\"Jane\",\"favoriteNumber\":42}")))
    .assertEntity("Person:Jane - favoriteNumber: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.

sourceimport spray.json.JsValue
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"""
}