Akka http: Акка потоки против актеров построить службу отдыха

Когда дело доходит до создания веб-службы REST с 60+ API на akka http. Как я могу выбрать, следует ли мне идти с аккскими потоками или аккой? В своем сообщении Jos показывает два способа создания API на 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)
    }
  }