handleWith
Signature
def handleWith[A, B](f: A => B)(implicit um: FromRequestUnmarshaller[A], m: ToResponseMarshaller[B]): Route
Description
Completes the request using the given function. The input to the function is produced with the in-scope entity unmarshaller and the result value of the function is marshalled with the in-scope marshaller. handleWith
can be a convenient method combining entity
with complete
.
The handleWith
directive is used when you want to handle a route with a given function of type A => BFunction<A,B>. handleWith
will use both an in-scope unmarshaller to convert a request into type A and an in-scope marshaller to convert type B into a response. This is helpful when your core business logic resides in some other class or you want your business logic to be independent of the REST interface written with akka-http. You can use handleWith
to “hand off” processing to a given function without requiring any akka-http-specific functionality.
handleWith
is similar to produce
. The main difference is handleWith
automatically calls complete
when the function passed to handleWith
returns. Using produce
you must explicitly call the completion function passed from the produce
function.
See marshalling and unmarshalling for guidance on marshalling entities with akka-http.
Examples
The following example uses an updatePerson
function with a Person
case class as an input and output. We plug this function into our route using handleWith
.
- Scala
-
source
case class Person(name: String, favoriteNumber: Int)
- Java
-
source
static public 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 updatePerson = (person: Person) => { //... some processing logic... //return the person person } val route = post { handleWith(updatePerson) } // tests: Post("/", HttpEntity(`application/json`, """{ "name": "Jane", "favoriteNumber" : 42 }""")) ~> route ~> check { mediaType shouldEqual `application/json` responseAs[String] should include(""""name":"Jane"""") responseAs[String] should include(""""favoriteNumber":42""") }
- Java
-
source
import static akka.http.javadsl.server.Directives.handleWith; final Unmarshaller<HttpEntity, Person> unmarshaller = Jackson.unmarshaller(Person.class); final Marshaller<Person, HttpResponse> marshaller = Marshaller.entityToOKResponse(Jackson.<Person>marshaller()); final Function<Person, Person> updatePerson = person -> { //... some processing logic... //return the person return person; }; final Route route = handleWith(unmarshaller, marshaller, updatePerson); // tests: final TestRouteResult routeResult = testRoute(route).run( HttpRequest.POST("/") .withEntity( HttpEntities.create( ContentTypes.APPLICATION_JSON, "{\"name\":\"Jane\",\"favoriteNumber\":42}" ) ) ); routeResult.assertMediaType(MediaTypes.APPLICATION_JSON); routeResult.assertEntity("{\"favoriteNumber\":42,\"name\":\"Jane\"}");
The PersonJsonSupport object handlesprevious example uses also Json Support via Jackson to handle both marshalling and unmarshalling of the Person case class.
sourceimport spray.json.{ DefaultJsonProtocol, RootJsonFormat }
object PersonJsonSupport extends DefaultJsonProtocol with SprayJsonSupport {
implicit val personFormat: RootJsonFormat[Person] = jsonFormat2(Person.apply)
}