Dav*_*iro 1 scala http akka http-status-code-404 akka-http
我正在努力实现非常简单的事情。
说,我有一个REST API。当我打电话
/api/recipe/1
Run Code Online (Sandbox Code Playgroud)
我想将一种资源作为json返回。
当我打
/api/recipe/2
Run Code Online (Sandbox Code Playgroud)
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)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的编译错误:
[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
Run Code Online (Sandbox Code Playgroud)
基于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))
}
}
}
Run Code Online (Sandbox Code Playgroud)
当配方存在时(例如/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可用,则Akka将返回响应作为json(如果值为)Some(v)或的空200响应None。如果使用spray-json,则创建一个RootJsonFormat[T]隐式对象并添加import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._。其他编组库也有类似的支持隐式。
要为None您生成404,需要complete使用rejectEmptyResponse指令包装。
| 归档时间: |
|
| 查看次数: |
3909 次 |
| 最近记录: |