我正在尝试实现非常简单的事情。
比如说,我有一个 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 以便能够 complete(Future[None[T]])
返回 404 Not found
。
我正在寻找一种适用于任何 Future[None]
返回值的通用方法。
最佳答案
如果你 complete(Future[Option[T]])
并且有合适的 Json Marshaller 可用,如果值为 Some(v)<,Akka 将以 json 形式返回响应
或 None
的空 200 响应。如果您使用 spray-json 创建一个 RootJsonFormat[T]
隐式并添加 import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
。其他编码库也有类似的隐式支持。
要为 None
生成 404,您需要用 rejectEmptyResponse
包装 complete
指令。
关于scala - Akka Http返回404未找到,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39048510/