我正在寻找一种转换函数的方法,该函数采用基本参数类型并使用它来处理akka HttpRequest
。我希望自动处理Path
并将其传递给函数。
举个例子,给出一些功能
def foobar(str : String, i : Int, l : Long) : String = ???
有一种方法可以提升"提升"处理Path
的功能。 URL路径示例可以是
/ foobar的/爱因斯坦/二千〇一十六分之四十二
提升功能如下所示:
import akka.http.scaladsl.model.Uri.Path
import akka.http.scaladsl.server.Directive
type SomeFunctionType = ???
def lifter(function : SomeFunctionType, path : Path) : Directive = {
val funcResult = ??? //somehow call function on the Path elements
complete(funcResult)
}
然后可以按以下方式使用:
val route =
get {
pathPrefix("foobar") {
extractUnmatchedPath { remainingPath =>
lifter(foobar, remainingPath)
}
}
}
此提升函数必须遍历函数参数类型,并在将值传递给函数之前将相应的Path部分转换为匹配类型。示例网址将使用调用foobar("enstein", 42, 2016)
的结果完成。
无论如何在图书馆中这样做?如果没有,有没有办法定义升降机?
提前感谢您的考虑和回应。
答案 0 :(得分:1)
您似乎想要创建Route
而不是Directive
。不同之处在于Route
实际处理请求,而Directive
包含具有更多功能的路由。您似乎想要最终处理请求,因此它应该是Route
。
您似乎在寻找一种适用于所有功能的非常通用的解决方案。目前这只是非常困难(甚至不可能),因为你不知何故需要指定如何解析参数。 spray-routing / akka-http路由实际上有点劝阻这种风格,而采用更明确的做事方式。
E.g。给定您(String, Int, Long) => Route
的给定函数定义,路径将如下所示:
def foobar(str: String, i: Int, l: Long): Route = complete(s"$str : $i : $l") // example implementation
// usage
path("foobar" / Segment / IntNumber / LongNumber)(foobar)
如果您无法转换foobar以返回路线,您还可以创建一个帮助器来转换函数,如下所示:
def foobar(str: String, i: Int, l: Long): String = s"$str : $i : $l"
def fromStringFunc3[T1, T2, T3](f: (T1, T2, T3) ⇒ String): (T1, T2, T3) ⇒ Route =
(t1, t2, t3) ⇒ complete(f(t1, t2, t3))
// usage
path("foobar" / Segment / IntNumber / LongNumber)(fromStringFunc3(foobar))
你必须为所有的arities重新创建这个函数(或者使用shapeless构建一些更灵活的东西,这是一种高级练习;)。