I am currently using playframework for my Http stuff and want to go to
Akka-HTTP for the new project. However from my reading and playing with
Akka-Http it seems that I have to stuff a ton of logic into the routes and
I don't like that. Consider the following from the docs:
public class JacksonExampleTest extends AllDirectives {
private Route createRoute() {
return route(
get(() ->
pathPrefix("item", () ->
path(longSegment(), (Long id) -> {
final CompletionStage<Optional<Item>> futureMaybeItem =
fetchItem(id);
return onSuccess(() -> futureMaybeItem, maybeItem ->
maybeItem.map(item -> completeOK(item, Jackson.marshaller()))
.orElseGet(() -> complete(StatusCodes.NOT_FOUND, "Not Found"
))
);
}))),
post(() ->
path("create-order", () ->
entity(Jackson.unmarshaller(Order.class), order -> {
CompletionStage<Done> futureSaved = saveOrder(order);
return onSuccess(() -> futureSaved, done ->
complete("order created")
);
})))
);
}
}
This is fine but I think of the size of API we are building and it
certainly WONT be fine then. There is way too much logic in the routes
file. I would like to keep that logic in the PRA and not the routes class
but I cant figure out how to do it. This is how I do it in playframework
currently.
routes.conf
POST /refund controllers.
Application.refund
public class Application extends AbstractController {
@UserAware
public CompletionStage<Result> refund() {
return RefundActor.invoke(getCurrentUserSession(), request());
}
}
public class RefundActor extends UntypedActor {
private final CompletableFuture<Result> future;
private final UserSession userSession;
private final RefundJson form;
private RefundResultsInfo results;
public RefundActor(final CompletableFuture<Result> future, final
UserSession userSession, final RefundJson form) {
super(future);
UserActivityActor.shardRegion().tell(new UserActivityActor.
RefundBetSlip(userSession.getUserId(),
userSession, form.getBetSlipId(), false, form.
getSubmissionTime()), getSelf());
}
public static CompletableFuture<Result> invoke(final UserSession
userSession, final Http.Request request) {
return withValidJson(RefundActor.class, request, RefundJson.class,
form -> {
final CompletableFuture<Result> future = new CompletableFuture
<>();
Ruckus.getActorSystem().actorOf(Props.create(RefundActor.class,
future, userSession, form));
return future;
});
}
@Trace(dispatcher = true)
@Override
public void onReceive(final Object message) throws Exception {
try {
if (message instanceof RefundResultsInfo) {
final String json = JsonUtilities.asJsonString(new
RefundResultsJson(results));
final Result result = Results.ok(json).as("application/json;
charset=utf-8")
.withHeader(CACHE_CONTROL, "public, max-age=" + 0);
future.complete(result);
getContext().stop(getSelf());
} else if (message instanceof ReceiveTimeout) {
handleReceiveTimeout();
} else {
unhandled(message);
}
} catch (final Exception ex) {
handleException(ex);
}
}
}
As you can see, the Play Route calls the PRA using a static method to get a
future (a home-cooked ASK pattern) and then returns the info back to the
user by rendering the result in the actor body. I have had to sanitize this
from proprietary code so excuse me if something looks odd, there are
actually a lot of tools in the real base class and the re is a ton of logic
being performed.
I would like to do something similar with Akka-Http but if I could keep it
in the actor space that would be even better. I would like to define the
route in the PRA as well so that all the API class has to do is enumerate
the routes. My initial efforts have failed because to get to the route DSL
you have to extend AllDirectives and that doesn't work if you want to
extend UntypedActor. Also I want the complete ad other methods available
inside the PRA and preferably in the receive loop so that I don't have
create intermediate return types just to send back to the route.
Thanks in advance.
Has anyone tried anything similar? Are there best practices?
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ:
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.