Akka Http返回404 Not Found

时间:2016-08-19 22:29:12

标签: 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才能{@ 1}}返回complete(Future[None[T]])

我正在寻找适用于任何404 Not found返回值的通用方法。

1 个答案:

答案 0 :(得分:5)

如果你Some(v)并且有一个合适的Json Marshaller可用,如果值NoneRootJsonFormat[T]的空200响应,Akka将以json的形式返回响应。如果使用spray-json,则隐式创建import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._并添加None。其他编组库也有类似的支持含义。

要为complete生成404,您需要使用rejectEmptyResponse指令包装@cython.boundscheck(False) @cython.wraparound(False) def add1_ravel(np.ndarray xs): cdef unsigned long i cdef double[::1] aview narray = xs.ravel() aview = narray for i in range(aview.shape[0]): aview[i] += 1 # return xs if the memory is shared if not narray.flags['OWNDATA'] or np.may_share_memory(xs, narray): return xs # otherwise new array reshaped shape = tuple(xs.shape[i] for i in range(xs.ndim)) return narray.reshape(shape)

相关问题