我正在Spray中编写一个自定义指令,用于管理任何用户请求的速率限制。
我将在某处处理LimitManager
处理每个请求的自定义限制和规则。此LimitManager
所需的唯一信息是userInfo
和currentRoute
,即不同路线的不同限制。
所以我可能会在指令中得到类似的东西:
def ensureLimit(): Directive0 =
if (LimitManager.isAuthorized(userInfo, currentRoute)) {
pass
} else {
reject
}
如何在指令中获取请求上下文,以便我可以向LimitManager
提供正确的信息?
答案 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
指令来获取上下文,然后使用map
或flatMap
制作您自己的内容:
val myDirective = extract(identity) map { ctx => /* Your directive */ }