如何在自定义指令中获取请求上下文?

时间:2014-07-04 22:20:14

标签: spray

我正在Spray中编写一个自定义指令,用于管理任何用户请求的速率限制。

我将在某处处理LimitManager处理每个请求的自定义限制和规则。此LimitManager所需的唯一信息是userInfocurrentRoute,即不同路线的不同限制。

所以我可能会在指令中得到类似的东西:

def ensureLimit(): Directive0 =
  if (LimitManager.isAuthorized(userInfo, currentRoute)) {
    pass
  } else {
    reject
  }

如何在指令中获取请求上下文,以便我可以向LimitManager提供正确的信息?

1 个答案:

答案 0 :(得分:7)

在Spray中,每个指令都是Route上的一个函数,它是函数RequestContext => Unit的别名。但是在强大的Scala暗示的帮助下,Routing DSL有助于隐藏它,但你可以写这样的东西:

val route: Route = get { (ctx: RequestContext) => // this can be omitted, just for info
  ctx.complete("Hello")
}

它与:

相同
val route: Route = get { complete("Hello") }

但是有一些复杂的语法技巧。

记住!你永远不应该这样写:

val route = get { ctx =>
  complete("Alloha")
}

此处complete会转换为ctx => ctx.complete("Hello"),因此您会在请求中返回此功能,并且无法完成实际请求。

所以你可以通过一种方式来做,只需作为参数传递。您也可以使用extract指令来获取上下文,然后使用mapflatMap制作您自己的内容:

val myDirective = extract(identity) map { ctx => /* Your directive */ }