指令如何在Spray中工作?

Jav*_*Man 2 spray

我想了解Spray中的指令是如何工作的.根据文件:

指令的一般解剖如下:

name(arguments) { extractions =>
  ... // inner Route
}
Run Code Online (Sandbox Code Playgroud)

我的基本理解是在下面的代码片段中,32作为参数传递给方法test.

test {
  32
}
Run Code Online (Sandbox Code Playgroud)

但是,在上面的指令name示例中,所谓的参数被传递到内部路由,这是一个匿名函数.

有人可以帮我理解语法和流程,从如何提取参数并传递到内部路径?

lmm*_*lmm 9

你的语法传递32给函数是对的test.你缺少的是a Directive 接受一个函数作为参数(记住,我们现在正在进行函数式编程,因此函数是值).如果你想写这个:

path(IntNumber) {
  userId =>
    complete(s"Hello user $userId")
}
Run Code Online (Sandbox Code Playgroud)

以较少的DSL-ey方式,您可以这样做:

val innerFunction: Int => Route = {userId => complete(s"Hello user $userId")}
(path(IntNumber))(innerFunction)
Run Code Online (Sandbox Code Playgroud)

甚至这个:

def innerMethod(userId: Int): Route = complete(s"Hello user $userId")
(path(IntNumber))(innerMethod)
Run Code Online (Sandbox Code Playgroud)

实际完成这项工作的机制是......复杂; 这个方法可以Directive隐式转换为函数:

implicit def pimpApply[L <: HList](directive: Directive[L])(implicit hac: ApplyConverter[L]): hac.In ? Route = f ? directive.happly(hac(f))
Run Code Online (Sandbox Code Playgroud)

这是使用"磁体模式"来选择一个合适的hac,因此如果指令提取参数,或者内部路径中的值(普通路径),它可以在内部路径中使用一个函数(具有适当数量的参数)如果指令不提取参数.代码看起来比它复杂,因为scala没有直接支持完全依赖类型,所以我们必须通过implicits来模拟它.看看ApplyConverterInstances这个必要的可怕代码:/.

当我们获得实际路线时,实际提取全部发生在happly特定指令的方法中.(如果HList到处都使用了一切,我们大多可以避免/忽略前面的恐怖).大多数extract-ey指令(例如path)最终调用hextract:

def hextract[L <: HList](f: RequestContext ? L): Directive[L] = new Directive[L] {
  def happly(inner: L ? Route) = ctx ? inner(f(ctx))(ctx)
}
Run Code Online (Sandbox Code Playgroud)

记住a Route实际上只是一个RequestContext => Unit,所以这会返回一个Route,当传递时RequestContext:

  1. 运行f它,提取需要提取的东西(例如URL路径组件)
  2. 运行inner ; inner是从例如路径分量到内部路线的函数.
  3. 在上下文中运行内部路径.

(以下是通过评论对话的mod编辑的):

从根本上说它非常优雅,你可以看到所有的喷码和普通的scala代码(我真的建议你在困惑时阅读源代码).但是与之相关的"桥接"部分ApplyConverter是复杂的,而且真的没有办法解决这个问题; 它试图用一种并非真正为它们设计的语言来完全依赖类型.

你必须记住,喷涂路由DSL是DSL; 这是几乎任何其他语言中你必须拥有的外部配置文件.我想不出一个单一的Web框架在路由定义方面提供了相同的灵活性,喷涂可以实现完整的编译时类型安全性.所以是的,喷涂的一些东西很复杂 - 但正如引用的那样,容易的东西应该是容易的,而且应该是可能的.所有scala级别的东西都很简单; 喷雾是复杂的,但在另一种语言中会更复杂(不可思议).