I want to have an actor based service which is accessible via http.
I'm new to akka, but after researching I came to the conclusion that using akka http will be the best approach for me.
I'm implementing a server that uses the akka http like so:
class MyServer extends AllDirectives {
private final Http http;
private final Materializer materializer;
private final Flow<HttpRequest, HttpResponse, NotUsed> routes;
private ServerBinding binding;
MyServer(final ActorSystem system) {
this.http = Http.get(system);
this.materializer = ActorMaterializer.create(system);
this.routes = this.createRoutes().flow(system, materializer);
}
CompletionStage<ServerBinding> start() {
return this.http
.bindAndHandle(this.routes, ConnectHttp.toHost("localhost", DEFAULT_PORT), this.materializer)
.thenApplyAsync(serverBinding -> {
this.binding = serverBinding;
return serverBinding;
});
}
CompletionStage<BoxedUnit> stop() {
return this.binding.unbind();
}
private Route createRoutes() {
// create routes
}
}
In the createRoutes method I want to create an hierarchical route tree (or forest) using directives, something like:
private Route createRoutes() {
return pathPrefix("typeOne", () ->
path(PathMatchers.segment(), id ->
get(() -> handleTypeOneGetRequest(id))
.orElse(post(() -> handleTypeOnePostRequest(id, requestData)))
)
).orElse(pathPrefix("typeTwo", () ->
path(PathMatchers.segment(), id ->
get(() -> handleTypeTwoGetRequest(id))
.orElse(post(() -> handleTypeTwoPostRequest(id, requestData)))
)
));
}
When handling requests (handleTypeOneGetRequest for example) I'd like to pass a message to the appropriate actor (TypeOne for example) and return an async response that will be fulfilled when a response message returns from the actor.
My problem is that I can't figure out how to access the RequestContext when handling the directives.
My questions are:
- How to I obtain the
RequestContextin the directive? - Am I going about this the right way? Is there a better approach?