2013-03-11 131 views
16

我已经返回一个选项[ProductDoc]在未来的服务(作为阿卡问)喷雾路由404响应

怎样在喷洒路由响应,这样一个有效的产品repsonds与产品,但未知但是格式良好的人会返回404吗?

我想要的代码填写在这里的差距:

get { 
    path("products"/PathElement) { productID:String => 
     val productFuture = (productService ? ProductService.Get(productID)).mapTo[Option[ProductDoc]] 

     // THE CODE THAT GOES HERE SO THAT 
     // IF PRODUCT.ISDEFINED RETURN PRODUCT ELSE REJECT 

    } 
} 

我可以得到工作的唯一方法是使用这个可憎

get { 
    path(PathElement) { productID:String => 
     val productFuture = (productService ? ProductService.Get(productID)).mapTo[Option[ProductDoc]] 
     provide(productFuture).unwrapFuture.hflatMap { 
     case x => provide(x) 
     } { hResponse:shapeless.::[Option[ProductDoc], HNil] => 
     hResponse.head match { 
      case Some(product) => complete(product) 
      case None => reject 
     } 
     } 
    } 
    } 

这不可能是正确的方法为了实现这一点,当然?这似乎是一个非常简单的模式,必须已经由某人解决!

回答

17

Spray已经支持您的用例:默认情况下,将选项值None编组为EmptyEntity。这可能是您在进行任何更改之前所看到的内容:带空文档的200。有一个指令可将空白文档转换为404,rejectEmptyResponse,您可以在需要此行为的部分绕行部分路径。然后

您的路线看起来就像这样:

rejectEmptyResponse { 
    path("products"/PathElement) { productID:String => 
     val productFuture = // same as before 
     complete(productFuture) 
    } 
    } 

当然,你可以把rejectEmptyResponse路径内取决于你是否想用它来包装更多的线路零件。

更多信息:

+0

这是否意味着我的承诺必须在我的逻辑或dao层出现错误时返回成功,但返回空响应? – 2013-04-09 09:02:06

+0

我不完全明白你想达到什么。这个话题是关于'Future [Option [T]]'的。使用上面的结构,你可以返回'Success(Some(x))'作为常规响应,'Success(None)'返回404,'Failure(x)'返回错误响应。你在问什么?如果您有更具体的问题,请在喷雾用户邮件列表中询问。 – jrudolph 2013-04-09 14:48:16

+0

这听起来不对我喷出真的是支持这个用例。关于来自例如200个空的响应怎么样?删除命令?它会变成404吗? – dividebyzero 2015-06-13 19:11:55

0

我有同样的问题,前几天来到这个解决方案:

我加入这个方法我的演员

def failIfEmpty[T](item: Future[Option[T]], id: String) = { 
    (item map { 
     case Some(t) => t 
     case None => throw NotFoundException(Message(s"id '$id' could not be  found",`ERROR`)) 
    }) pipeTo sender 
} 

当然,你可以选择你喜欢的异常,NotFoundException是一个在你的结果我自己...

调用此的回答给您的男主角问(这是使用ReactiveMongo一个例子,你Future[Option]替换collection.find(query).headOption):

failIfEmpty(collection.find(query).headOption, id) 

然后,像下面的的ExceptionHandler添加到您的服务(如您的路线定义):

implicit val klaraExceptionHandler = ExceptionHandler.fromPF { 
    case InternalServerErrorException(messages) => complete(InternalServerError, messages) 
    case NotFoundException(message) => complete(NotFound, message) 
    case ValidationException(messages) => complete(PreconditionFailed, messages) 
    [and so on] 
} 

这样,您就可以处理,我的出现你的未来,结果几个不同的错误。