Когда дело доходит до создания веб-службы REST с 60+ API на akka http. Как я могу выбрать, следует ли мне идти с аккскими потоками или аккой? В своем сообщении Jos показывает два способа создания API на akka http, но он не показывает, когда я должен выбирать один над другим.
Akka http: Акка потоки против актеров построить службу отдыха
Ответ 1
Это сложный вопрос. Очевидно, оба подхода работают. Так что в определенной степени это вопрос вкуса/знакомства. Итак, теперь все, что я вижу сейчас, - это только мое личное мнение.
Когда это возможно, я предпочитаю использовать akka-stream из-за его более высокого уровня и безопасности типов. Но зависит ли это от жизнеспособного подхода от задачи REST API.
Акка-поток
Если ваш REST API - это услуга, например, отвечает на вопросы, основанные на внешних данных (например, API обменного курса обмена), предпочтительно реализовать его с использованием akka-потока.
Еще один пример, когда предпочтительным будет akka-stream, будет какой-то интерфейс базы данных, где задача REST API заключается в анализе параметров запроса, преобразовании их в запрос БД, выполнении запроса и преобразовании результата в соответствии с содержимым тип, запрошенный пользователем. В обоих случаях поток данных легко переносится на примитивы akka-stream.
Актеры
Пример, когда использование актеров предпочтительнее, может быть, если ваш API позволяет запрашивать и обновлять несколько постоянных участников кластера. В этом случае предпочтительным может быть либо решение на основе чистого актера, либо смешанное решение (анализ параметров запроса и перевод результатов с использованием akka-stream, остальные с использованием участников).
Другим примером, в котором может быть предпочтительным решение на основе актера, было бы, если у вас есть REST API для длительных запросов (например, websockets) и хотите развернуть конвейер обработки самого REST-интерфейса в кластере. Я не думаю, что что-то подобное в настоящее время возможно вообще с использованием akka-потока.
Резюме
Итак, чтобы подвести итог: посмотрите на поток данных каждого API и посмотрите, чисто ли он отображает примитивы, предлагаемые akka-stream. Если это так, используйте его с помощью akka-stream. В противном случае реализуйте использование участников или смешанное решение.
Ответ 2
Не забывайте фьючерсы!
Одно добавление, которое я сделал бы для Rudiger Klaehn, - это также рассмотреть вариант использования Future
. Сложность фьючерсов и управления ресурсами ExecutionContext
делает фьючерсы идеальными для многих, если не большинства, ситуаций.
Существует отличный пост в блоге, описывающий, когда Фьючерсы - лучший выбор, чем Актеры. Кроме того, обратное давление, предоставляемое Streams, имеет довольно тяжелые служебные расходы.
Просто потому, что вы сбиты с кролика, используя akka-http, не означает, что все concurrency внутри вашего обработчика запросов должны быть ограничены актерами или потоками.
Маршрут
Route
по своей сути включает фьючерсы в определении типа :
type Route = (RequestContext) ⇒ Future[RouteResult]
Поэтому вы можете испечь будущее прямо в своем маршруте, используя только функции и фьючерсы, никаких директив:
val requestHandler : RequestContext => HttpResponse = ???
val route : Route =
(requestContext) => Future(requestHandler(requestContext)) map RouteResult.Complete
директива onComplete
onComplete
Директива позволяет вам "развернуть" Будущее в вашем маршруте:
val route =
get {
val future : Future[HttpResponse] = ???
onComplete(future) {
case Success(httpResponse) => complete(httpResponse)
case Failure(exception) => complete(InternalServerError -> exception.toString)
}
}