2014-07-04 103 views
4

我在Spray中编写了一个自定义指令,用于管理任何用户请求的速率限制。如何获取自定义指令中的请求上下文?

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

所以我可能会最终不得不像这样的指令:

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

我怎样才能获得请求上下文中的指令中,所以我可以提供正确的信息给我LimitManager

回答

7

In Spray每个指令都是一个函数Route,它是函数RequestContext => Unit的别名。但随着强大的斯卡拉暗示的帮助下,路由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 */ } 
+1

要添加到记住!部分的思想延伸,你可能会遇到一种情况,你需要'RequestContext'引用,并且必须使用更多的指令(​​而不是'complete')。在这种情况下,您可以手动传递RequestContext对象。如果你需要处理期货:'get {ctx => onComplete(someFutureProducer(ctx)){...}(ctx)}' – Rich

相关问题