ccheneson
(Cyril Cheneson)
1
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.
ccheneson
(Cyril Cheneson)
3
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”))
}
ccheneson
(Cyril Cheneson)
4
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