AKKA HTTP: Is this a valid use of Route.seal?

301 views
Skip to first unread message

Alan Burlison

unread,
Mar 7, 2017, 5:32:37 PM3/7/17
to akka...@googlegroups.com
I have an Akka HTTP route for a REST API that first checks the base path, then  checks the user authentication is valid, adds some custom headers and extracts the base URI before processing the sub-routes. However if the URL doesn't match any of the sub-routes, request processing "rolls back" to the authentication step and I get an incorrect message about authentication failing.
​ ​
​I've wrapped the sub-route processing in Route.seal and that ​​means that I​ now get a "Not Found"
​for nonexistent paths, ​
as required
​. However the documentation says that Route.seal ​
​shouldn't really be needed for application code. Is this a valid use of Route.seal, or is there a better way to prevent route processing from "rolling back" past a specified point?​


def route: Route = {
  pathPrefix("rest" / "v1") {
    // If the request authenticates successfully, add the custom headers to the response
    // and extract the base URI we were called with.
    (combinedAuth & respondWithHeaders(versionHeaders) & baseUri ) { (sess, baseUri) => {
     // Process valid sub-routes, seal the route so we don't roll back past this point.
      Route.seal(concat(
        pathEndOrSingleSlash { topRoute(sess, baseUri) },
        pathPrefix("users")  { userRoute(sess, baseUri) }
      ))}
    }
  }
}


--
Alan Burlison
--

Alan Burlison

unread,
Mar 8, 2017, 10:57:37 AM3/8/17
to akka...@googlegroups.com
Anyone have any suggestions? Thanks!

On 07/03/17 22:32, Alan Burlison wrote:
> I have an Akka HTTP route for a REST API that first checks the base path,
> then checks the user authentication is valid, adds some custom headers and
> extracts the base URI before processing the sub-routes. However if the URL
> doesn't match any of the sub-routes, request processing "rolls back" to the
> authentication step and I get an incorrect message about authentication
> failing.
> ​ ​
> ​I've wrapped the sub-route processing in Route.seal and that ​​
> means that I​ now get a "Not Found" ​for nonexistent paths, ​as
> required. However the documentation says that Route.seal ​ ​shouldn't

Johannes Rudolph

unread,
Mar 15, 2017, 12:26:20 PM3/15/17
to Akka User List
Hi Alan,

yes, that's a valid use case. The route tree is usually traversed completely until a Route matches. But if you know that the search can be cut short, then `seal` is definitely a good solution. Another solution would be to use only `handleRejections` which would have the advantage that only rejections are handled and exceptions will still bubble up and run through the exception handlers you have defined further up in your route.

Johannes

Alan Burlison

unread,
Mar 16, 2017, 5:47:31 AM3/16/17
to akka...@googlegroups.com
On 15/03/2017 16:26, 'Johannes Rudolph' via Akka User List wrote:

> yes, that's a valid use case. The route tree is usually traversed
> completely until a Route matches. But if you know that the search can be
> cut short, then `seal` is definitely a good solution.

That's exactly the case here - once the request authentication has
succeeded (multiple forms are provided) then there's no point
backtracking into it as any subsequent errors are path, parameter, data
etc problems.

> Another solution would be to use only `handleRejections` which would
> have the advantage that only rejections are handled and exceptions
> will still bubble up and run through the exception handlers you have
> defined further up in your route.

I started by using an implicit rejection handler but had to switch to an
explicit handleRejections directive for some reason I don't understand.
I moved the implicit handler into a base class of the classes that are
providing the route segments and since then it's not being picked up,
even though the docs for implicit resolution say that base classes are
in the search path. I haven't figured out what the problem is, but as an
explicit handler is clearer anyway, I'm tempted to just move on.

I'm writing an emulation of multiple instances of an existing REST
service, for testing purposes. It's rather neat to see 1000 Akka-based
REST services running inside a single JVM :-) At the moment it's just at
the "hello world" stage so memory & CPU will increase but I have no
reason to believe I won't be able to support many hundreds of emulated
services from a single JVM, and there's Akka clustering for beyond that.

--
Alan Burlison
--
Reply all
Reply to author
Forward
0 new messages