【发布时间】:2016-08-26 08:39:33
【问题描述】:
我正在尝试实现非常简单的事情。
说,我有一个 REST API。当我打电话时
/api/recipe/1
我想将资源作为 json 格式返回。
当我击中时
/api/recipe/2
应该返回 404 Not Found HTTP 响应。就这么简单。
显然我错过了一些关于路由指令如何工作的东西,因为我无法将它们组合成尊重上述逻辑。
很遗憾,我找不到任何具体的例子,官方文档也不是特别有用。
我正在尝试这样的事情,但代码给出了编译错误:
class RecipeResource(recipeService: RecipeService)(implicit executionContext: ExecutionContext) extends DefaultJsonProtocol {
implicit val recipeFormat = jsonFormat1(Recipe.apply)
val routes = pathPrefix("recipe") {
(get & path(LongNumber)) { id =>
complete {
recipeService.getRecipeById(id).map {
case Some(recipe) => ToResponseMarshallable(recipe)
// type mismatch here, akka.http.scaladsl.marshalling.ToResponseMarshallable
// is required
case None => HttpResponse(StatusCodes.NotFound)
}
}
}
}
}
更新
为了更清楚,这里是recipeService 的代码:
class RecipeService(implicit executionContext: ExecutionContext) {
def getRecipeById(id: Long): Future[Option[Recipe]] = {
id match {
case 1 => Future.successful(Some(Recipe("Imperial IPA")))
case _ => Future.successful(None)
}
}
}
我得到的编译错误:
[error] /h......../....../...../RecipeResource.scala:22: type mismatch;
[error] found : scala.concurrent.Future[Object]
[error] required: akka.http.scaladsl.marshalling.ToResponseMarshallable
[error] recipeService.getRecipeById(id).map {
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
更新 2
根据 leachbj 的回答,我摆脱了路由中不必要的模式匹配。现在代码编译并如下所示:
class RecipeResource(recipeService: RecipeService)(implicit executionContext: ExecutionContext) extends DefaultJsonProtocol {
implicit val recipeFormat = jsonFormat1(Recipe.apply)
val routes = pathPrefix("recipe") {
(get & path(LongNumber)) { id =>
complete(recipeService.getRecipeById(id))
}
}
}
当配方存在时(例如 /api/recipe/1),我会收到 JSON 响应和 200 OK,这是预期的。
现在,如果资源不存在(例如/api/recipe/2),响应为空,但会收到200 OK 状态代码。
我的问题是,我如何调整 akka-http 以使其能够返回 404 Not found 的 complete(Future[None[T]])。
我正在寻找一种适用于任何Future[None] 返回值的通用方法。
【问题讨论】:
-
getRecipeById的返回类型是什么? -
Future[Option[Recipe]] -
那么,当您针对该 id 运行查询时会得到什么?你得到一个无吗?
-
我只是一个简单的存根,如果 id 为 1,则返回
Some,否则返回None。代码已添加到帖子中。 -
您返回了两种不兼容的类型。您应该在范围内有一个隐式编组器。呼叫
ToResponseMarshallable是我在这里闻到的气味。编辑:我刚刚查看了我的一些 Akka-Http 代码...我返回了一个StatusCode元组 ->response并且根本不使用 ToResponseMarshallable。
标签: scala http akka http-status-code-404 akka-http