completeWith

Description

Uses the marshaller for a given type to produce a completion function that is passed to its inner route. You can use it to decouple marshaller resolution from request completion.

The completeWith directive works in conjunction with instanceOf and spray.httpx.marshalling to convert higher-level (object) structure into some lower-level serialized “wire format”. The marshalling documentation explains this process in detail. This directive simplifies exposing types to clients via a route while providing some form of access to the current context.

completeWith is similar to handleWith. The main difference is with completeWith you must eventually call the completion function generated by completeWith. handleWith will automatically call complete when the handleWith function returns.

Examples

The following example uses Json Support via Jackson to marshall a simple Person into a json request

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;
  }
}
final Marshaller<Person, HttpResponse> marshaller = Marshaller.entityToOKResponse(Jackson.<Person>marshaller());

//Please note that you can also pass completionFunction to another thread and use it there to complete the request.
//For example:
//final Consumer<Consumer<Person>> findPerson = completionFunction -> {
//  CompletableFuture.runAsync(() ->
//   /* ... some processing logic... */
//   completionFunction.accept(new Person("Jane", 42)));
//};
final Consumer<Consumer<Person>> findPerson = completionFunction -> {

  //... some processing logic...

  //complete the request
  completionFunction.accept(new Person("Jane", 42));
};

final Route route = completeWith(marshaller, findPerson);

// tests:
final TestRouteResult routeResult = testRoute(route).run(
        HttpRequest.GET("/")
);
routeResult.assertMediaType(MediaTypes.APPLICATION_JSON);
routeResult.assertEntity("{\"favoriteNumber\":42,\"name\":\"Jane\"}");

The findPerson takes an argument of type Consumer<Consumer<Person>> which is generated by the completeWith call. We can handle any logic we want in findPerson and call our completion function to complete the request.

The source code for this page can be found here.