Я пытаюсь добиться очень простой вещи.
Скажем, у меня есть REST API. Когда я звоню
/api/recipe/1
Я хотел бы, чтобы ресурс был возвращен в виде json.
Когда я ударил
/api/recipe/2
должен быть возвращен HTTP-ответ 404 Not Found. Просто как тот.
Очевидно, я что-то упускаю из виду, как работают директивы маршрутизации, поскольку я не могу составить их с учетом вышеупомянутой логики.
К сожалению, мне не удалось найти конкретного примера, а официальная документация не особенно полезна.
Я пытаюсь что-то вроде этого, но код дает ошибку компиляции:
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]
.
getRecipeById
? - person M.K.   schedule 20.08.2016Some
в случае, если id равен 1, иNone
в противном случае. Код добавлен в пост. - person David Siro   schedule 20.08.2016akka.http.scaladsl.marshalling.ToResponseMarshallable
как возвращаемый тип закрытия. Вывод компилятора добавлен в пост. - person David Siro   schedule 20.08.2016ToResponseMarshallable
— это запах, который я здесь чувствую. РЕДАКТИРОВАТЬ: я только что взглянул на часть своего кода Akka-Http... Я возвращаю кортежStatusCode
->response
и вообще не заморачиваюсь с ToResponseMarshallable. - person Chris Martin   schedule 20.08.2016