Akka Http return 404 未找到
Akka Http return 404 Not Found
我正在尝试实现非常简单的事情。
说,我有 REST API。当我打电话时
/api/recipe/1
我想将资源作为 json 进行 returned。
当我打
/api/recipe/2
404 Not Found HTTP 响应应该 returned。就这么简单。
很明显,我遗漏了一些关于路由指令如何工作的信息,因为我无法将它们组合成符合上述逻辑的内容。
不幸的是,我找不到任何具体示例,官方文档也不是特别有用。
我正在尝试类似的操作,但代码给出了编译错误:
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]])
return 404 Not found
.
我正在寻找适用于任何 Future[None]
return 值的通用方法。
如果你 complete(Future[Option[T]])
并且有合适的 Json Marshaller 可用,Akka 将 return 响应为 json 如果值为 Some(v)
或None
的空 200 响应。如果您使用 spray-json 创建一个 RootJsonFormat[T]
隐式并添加 import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
。其他编组库也有类似的隐式支持。
要为 None
生成 404,您需要使用 rejectEmptyResponse
指令包装 complete
。
我正在尝试实现非常简单的事情。
说,我有 REST API。当我打电话时
/api/recipe/1
我想将资源作为 json 进行 returned。
当我打
/api/recipe/2
404 Not Found HTTP 响应应该 returned。就这么简单。
很明显,我遗漏了一些关于路由指令如何工作的信息,因为我无法将它们组合成符合上述逻辑的内容。
不幸的是,我找不到任何具体示例,官方文档也不是特别有用。
我正在尝试类似的操作,但代码给出了编译错误:
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]])
return 404 Not found
.
我正在寻找适用于任何 Future[None]
return 值的通用方法。
如果你 complete(Future[Option[T]])
并且有合适的 Json Marshaller 可用,Akka 将 return 响应为 json 如果值为 Some(v)
或None
的空 200 响应。如果您使用 spray-json 创建一个 RootJsonFormat[T]
隐式并添加 import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
。其他编组库也有类似的隐式支持。
要为 None
生成 404,您需要使用 rejectEmptyResponse
指令包装 complete
。