Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a Future inside an Akka HTTP Directive?

I currently have a directive that I'm using to secure resources in an Akka HTTP app, like so:

def authenticate: Directive1[Login] =
  optionalHeaderValueByName("Authorization") flatMap {
    val accessToken = authz.split(' ').last
    case Some(authz) =>
      LoggedInUser findByAccessToken accessToken match {
        case Some(user) => provide(user)
        case None       => reject(AuthorizationFailedRejection)
      }
    case None => reject(AuthorizationFailedRejection)
  }

where LoggedInUser.findByAccessToken() makes a blocking query against a database, I would like to switch this for an asynchronous ask to an actor which which can provide the same data, I'm OK with passing in the ActorRef as a parameter to the directive but I cannot work out how to handle the Future that the ask returns.

None of the Directive1 examples that come with Akka HTTP seem to do this (at least I could;t find any) although there are examples of directives returning Route which do.

Is what I want to do even possible? Is a possible approach to create a StandardRoute subclass with a field for the user credentials and return that somehow?

like image 817
Ian Phillips Avatar asked Oct 09 '15 14:10

Ian Phillips


People also ask

What are directives in Akka HTTP?

A “Directive” is a small building block used for creating arbitrarily complex route structures. Akka HTTP already pre-defines a large number of directives and you can easily construct your own: Basics. Structure.

What does DSL stand for in Akka?

The grand-child will be supervised by the child; the supervisor strategy for this relationship can also be configured using a DSL element (supervision directives are part of the Act trait):

What are HTTP directives?

The IBM® HTTP Server for i is configured using directives. A directive is used to define an attribute of the HTTP Server or how the HTTP Server operates. For example, the Listen directive defines what port the HTTP Server should wait on to handle incoming requests.

What is entity in Akka?

The entity method will either pass the value to the inner route or map the exception to a Rejection . The entity directive works in conjunction with as and akka. http. scaladsl. unmarshalling to convert some serialized “wire format” value into a higher-level object structure.


1 Answers

Yes, it is possible. As far as I understand you need something like this:

def authenticate: Directive1[Login] = {
  def findByAccessToken(accessToken:String): Future[Option[Login]] = ???
  optionalHeaderValueByName("Authorization").flatMap {
    case Some(authz) =>
      val accessToken = authz.split(' ').last
      onSuccess(findByAccessToken(accessToken)).flatMap {
        case Some(user) => provide(user)
        case None       => reject(AuthorizationFailedRejection)
      }
    case None => reject(AuthorizationFailedRejection)
  }
}
like image 140
Nyavro Avatar answered Nov 15 '22 20:11

Nyavro