Handling POST Request Using Akka-http in a Akka-actor System

Posted on the 08 November 2017 by Araldam @araldam
Akka-htp is a well known module for providing full server side as well as client side http stack currently supporting Scala and Java language bindings. Among other Java Rest frameworks/libraries such as Spring-boot, Play Framework, JAX-RS, Jersy or Scalatra, akka-http is more preferable in applications where high throughput and concurrency is expected.
Akka-http is not a full MVC framework like Play or not require a container to run like scalatra. As it is based on akka-actor and akka-stream modules inherently reactive and works well with message driven systems. As it supports for different levels(low level and high levl) of APIs makes it easy to adopt and ease of deployment.
Here is a simple example of using Akka-http high level API in Java in a akka-actor system.
First we need following dependencies to be included in our project.

Here we initialize the http server and bind with the akka system. 
We can define our router class by extending 'AllDirectives' class as follows. We use this to get a Route object while initializing the 'routeFlow' as above.
import akka.http.javadsl.model.ContentTypes;
import akka.http.javadsl.model.HttpResponse;
import akka.http.javadsl.server.AllDirectives;
import akka.http.javadsl.server.Route;
import static akka.http.javadsl.server.PathMatchers.integerSegment;
import static akka.http.javadsl.server.PathMatchers.segment;
public class Router extends AllDirectives {
//host:port/api/{userId}/{resourceId}
public Route createRoute() {
return route(
pathPrefix(segment("api"),
() -> pathPrefix(integerSegment(),
userId -> pathPrefix(segment(),
resourceId -> pathEndOrSingleSlash(
() -> processRequest(userId, resourceId))
)
)
)
);
}
}

In the processRequest method we provide the POST request handler which returns a 'akka.http.javadsl.server.Route' instance.
    private Route processRequest(args...) {
return post(() -> entity(handler...)
);
}

Based on the request body (Content-Type) we need to use a specific Unmarshaller to access request data. As an example in order to parse the JSON request body we can use a Unmarshaller provided by the 'akka-http-jackson-experimental_2.11' package, Gson or some other Unmarshaller.
Using akka.http.javadsl.marshallers.jackson.Jackson;
import akka.http.javadsl.marshallers.jackson.Jackson;
public Route processRequestUsingJackson(int userId,String resourceId) {
return post(() -> entity(Jackson.unmarshaller(Request.class),
content ->
completeWithFuture(
CompletableFuture.completedFuture(
HttpResponse.create()
.withEntity(ContentTypes.APPLICATION_JSON, "{\"msg\":\"Success\"}")
)
)
)
);
}

Using com.google.gson.Gson;
import com.google.gson.Gson;
private Route processRequestUsingGson(int userId,String resourceId) {
return post(() -> entity(Unmarshaller.entityToString(), content -> {
final Gson gson = new Gson();
final Request requestBody = gson.fromJson(content, Request.class);
return completeWithFuture(
CompletableFuture.completedFuture(
HttpResponse.create()
.withEntity(ContentTypes.APPLICATION_JSON, "{\"msg\":\"Success\"}")
)
);
}
)
);
}