Can a custom directive using another directive returns a Directive and not a Route?

Hi all,
With akka-http, is it possible to write a custom directive using a directive and returns a directive ?

I want to write a custom directive that

  • extracts some fields from a form

  • uses them to build an object ( from case class)

  • and pass it on to the next directive.

case class MyUser(name: String)
case object MyRejection extends Rejection

implicit class Multipart2Map(formData: Multipart.FormData) {
def toMap: Future[Map[String, Any]] = convertMultipartToMap(formData)
}

def httpToMap: Directive[Tuple1[Future[Map[String, Any]]]] = (post & entity(as[Multipart.FormData])).flatMap { x => provide(x.toMap) }

def httpToUser = httpToMap.flatMap { myMap =>
onComplete(myMap) {
case Success(m) => provide(MyUser(“mrtest”))
case Failure(er) => reject(MyRejection)
}
}

IntellijIDEA gives me an error that httpToUser returns a Route instead of a Directive

At end I would like to use it like:

httpToUser { myUser: MyUser =>
complete(“Ok”)
}

Directive1[T].flatMap is probably what you are looking for, it allows you to transform the T to another directive.

Hi @johanandren, thanks for your input.
Using flatMap, I still have the same error in the httpUser returned type:

Type mismatch, expected: Future[Map[String, Any]] => Directive[NotInferedR], actual: Future[Map[String, Any]] => server.Route

I have updated the code from the OP.

I have the feeling that it is due to the onComplete

The following snippet doesn’t throw any errors:

def httpToUse = httpToMap.flatMap { myMap =>
provide(MyUser(“mrtest”))
}

The following doesn’t give an error but it evaluates the type to Directive[Nothing]

def http2Request: Directive[Nothing] = httpToMap.flatMap { myMap =>
onComplete(myMap) flatMap {
case Success(m) => provide(MyUser(“mrtest”))
case Failure(er) => reject(MyRejection)
}
}

Changing Directive[Nothing] to Directive1[MyUser] also works and I can now compile.

I m interested to know why it couldn’t infer the right type MyUser