scala - Akka Http返回404未找到

标签 scala http akka http-status-code-404 akka-http

我正在尝试实现非常简单的事情。

比如说,我有一个 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/

相关文章:

scala - 如何在 Akka Http 中以编程方式调用 Route

python-3.x - 扭曲的端口 80 需要手动端口 80 并且无法正常工作

c++ - 将 tiff 图像转换为要作为二进制应用程序/八位字节流发布的字符串 (C++)

c - 服务器在限制连接总数时返回的正确 HTTP 状态代码是什么?

Akka 流 - 将接收器连接到源?

java - 如何将 java.util.List[java.lang.Double] 转换为 Scala 的 List[Double]?

scala - 在 Scala 中递归使用隐式方法

scala - ~> 运算符在 Spray.io 中到底意味着什么?

java - Akka 2.1.0-RC 集群路由器因找不到路由问题而终止

architecture - 用于 AKKA Actor 框架?