score:4

Accepted answer

After spending some time looking into this, the way the Filter system currently works it doesn't lend itself well to being applied to WebSocket requests.

The issue is that Filters work with an apply method taking a

nextFilter: RequestHeader => Future[Result]

where as WebSocket functions take a

f: RequestHeader => Future[Either[Result, Flow[In, Out, _]]]

So passing the WebSocket result through the Filter system doesn't really work.

However for my case, I was primarily interested in the logging filter. So as a workaround I created a custom version of acceptOrResult as follows:

def acceptOrResult[TIn, TOut](f: RequestHeader => Future[Either[Result, Flow[TIn, TOut, _]]])(implicit transformer: MessageFlowTransformer[TIn, TOut], materializer: Materializer, ec: ExecutionContext): WebSocket = {
    WebSocket { request =>
        f(request).map { fResult =>
            PostRequestLoggingFilter.apply(request,fResult.left.getOrElse(Ok))
            fResult.right.map(transformer.transform)
        }
    }
}

I needed to break the logic out of the PostRequestLoggingFilter into it's companion object's apply method so the above could function.

If the WebSocket request is Left, we have a Result; if it's Right then I just pass an Ok result. This could be applied to other filters as long as you don't mind the fact that they'll run after the WebSocket request.


Related Query

More Query from same tag