2013-03-11 125 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] 
} 

這樣,您就可以處理,我的出現你的未來,結果幾個不同的錯誤。