entity
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 Rejection
Rejection
.
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 Rejection
Rejection
within the entity
directive. The following table lists how exceptions are mapped to rejections:
Left(exception) | Rejection |
---|---|
ContentExpected |
RequestEntityExpectedRejection RequestEntityExpectedRejection |
UnsupportedContentType |
UnsupportedRequestContentTypeRejection UnsupportedRequestContentTypeRejection , which lists the supported types |
MalformedContent |
MalformedRequestContentRejection MalformedRequestContentRejection , with an error message and cause |
Examples
The following example uses spray-json
Json 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
-
source
case 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
-
source
public 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
-
source
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" }
- Java
-
source
import 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"""
}