When it comes to creating a REST web service with 60+ API on akka http. How can I choose whether I should go with akka streams or akka actors? In his post, Jos shows two ways to create an API on akka http but he doesn't show when I should select one over the other.
Akka HTTP is mostly used for making integration layers based on HTTP. A user can build the application based on their requirements, and Akka HTTP can be used to cater to the needs of HTTP integration.
Spring, Scala, Erlang, Kafka, and Spring Boot are the most popular alternatives and competitors to Akka.
Akka HTTP is not a framework–not because we don't like frameworks–but to provide maximum flexibility. For example, you might use the Play framework to implement browser-based interactions or Lagom framework for creating microservices, both of them are also based on Akka.
Akka HTTP also provides an embedded, Reactive-Streams-based, fully asynchronous HTTP/1.1 server implemented on top of Streams. It supports the following features: Full support for HTTP persistent connections.
This is a difficult question. Obviously, both approaches work. So to a certain degree it is a matter of taste/familiarity. So everything following now is just my personal opinion.
When possible, I prefer using akka-stream due to its more high-level nature and type safety. But whether this is a viable approach depends very much on the task of the REST API.
If your REST API is a service that e.g. answers questions based on external data (e.g. a currency exchange rate API), it is preferable to implement it using akka-stream.
Another example where akka-stream would be preferable would be some kind of database frontend where the task of the REST API is to parse query parameters, translate them into a DB query, execute the query and translate the result according to the content-type requested by the user. In both cases, the data flow maps easily to akka-stream primitives.
An example where using actors would be preferable might be if your API allows querying and updating a number of persistent actors on a cluster. In that case either a pure actor-based solution or a mixed solution (parsing query parameters and translating results using akka-stream, do the rest using actors) might be preferable.
Another example where an actor-based solution might be preferable would be if you have a REST API for long-running requests (e.g. websockets), and want to deploy the processing pipeline of the REST API itself on a cluster. I don't think something like this is currently possible at all using akka-stream.
So to summarize: look at the data flow of each API and see if it maps cleanly to the primitives offered by akka-stream. If this is the case, implement it using akka-stream. Otherwise, implement using actors or a mixed solution.
One addendum I would make to Rudiger Klaehn's fine answer is to also consider the use case of a Future
. The composability of Futures and resource management of ExecutionContext
make Futures ideal for many, if not most, situations.
There is an excellent blog post describing when Futures are a better choice than Actors. Further, the back-pressure provided by Streams comes with some pretty hefty overhead.
Just because you're down the rabbit hole using akka-http does not mean all concurrency within your request handler has to be confined to Actors or Streams.
Route
Route
inherently accomodates Futures in the type definition:
type Route = (RequestContext) ⇒ Future[RouteResult]
Therefore you can bake a Future directly into your Route using only functions and Futures, no Directives:
val requestHandler : RequestContext => HttpResponse = ???
val route : Route =
(requestContext) => Future(requestHandler(requestContext)) map RouteResult.Complete
onComplete Directive
The onComplete
Directive allows you to "unwrap" a Future within your Route:
val route =
get {
val future : Future[HttpResponse] = ???
onComplete(future) {
case Success(httpResponse) => complete(httpResponse)
case Failure(exception) => complete(InternalServerError -> exception.toString)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With