web-dev-qa-db-ja.com

akka http:AkkaストリームとアクターがRESTサービスを構築する

Akkahttpで60以上のAPIを使用してREST Webサービスを作成する場合。akkaストリームとakkaアクターのどちらを使用するかを選択するにはどうすればよいですか?彼の post =、Josはakka httpでAPIを作成する2つの方法を示していますが、どちらを選択する必要があるかについては示していません。

20
Mutaz

これは難しい質問です。明らかに、両方のアプローチが機能します。したがって、ある程度、それは味/親しみやすさの問題です。したがって、これから続くことはすべて私の個人的な意見です。

可能であれば、より高度な性質と型安全性のために、akka-streamを使用することを好みます。しかし、これが実行可能なアプローチであるかどうかは、RESTAPIのタスクに大きく依存します。

アッカストリーム

REST AP​​Iがサービスである場合、たとえば外部データ(為替レートAPIなど)に基づいて質問に回答する場合は、akka-streamを使用して実装することをお勧めします。

Akka-streamが望ましい別の例は、REST AP​​Iのタスクがクエリパラメータを解析し、それらをDBクエリに変換し、クエリを実行し、それに応じて結果を変換することである、ある種のデータベースフロントエンドです。ユーザーが要求したコンテンツタイプに。どちらの場合も、データフローはakka-streamプリミティブに簡単にマッピングされます。

俳優

アクターの使用が望ましい例としては、APIでクラスター上の多数の永続アクターのクエリと更新が許可されている場合があります。その場合、純粋なアクターベースのソリューションまたは混合ソリューション(クエリパラメーターを解析し、akka-streamを使用して結果を変換し、残りはアクターを使用して実行する)のいずれかが望ましい場合があります。

アクターベースのソリューションが望ましい別の例は、長時間実行されるリクエスト(WebSocketなど)用のREST AP​​Iがあり、RESTの処理パイプラインをデプロイする場合です。 _クラスター上のAPI自体。私はこのようなことは現在可能ではないと思いますまったく akka-streamを使用します。

概要

要約すると、各APIのデータフローを見て、akka-streamによって提供されるプリミティブにきれいにマッピングされているかどうかを確認します。この場合は、akka-streamを使用して実装してください。それ以外の場合は、アクターまたは混合ソリューションを使用して実装します。

21
Rüdiger Klaehn

先物を忘れないでください!

Rudiger Klaehnのすばらしい答えに対する1つの補遺は、 Future のユースケースも検討することです。 Futuresの構成可能性とExecutionContextのリソース管理により、Futuresは、ほとんどではないにしても、多くの状況に理想的です。

優れた ブログ投稿 FuturesがActorsよりも優れた選択肢である場合を説明しています。さらに、Streamsによって提供される背圧には、かなり大きな オーバーヘッド が伴います。

Akka-httpを使用してうさぎの穴を掘り下げているからといって、リクエストハンドラー内のすべての同時実行性をアクターまたはストリームに限定する必要があるわけではありません。

ルート

Routeは本質的に先物に対応します 型定義

type Route = (RequestContext) ⇒ Future[RouteResult]

したがって、ディレクティブを使用せずに、関数とフューチャーのみを使用して、フューチャーをルートに直接ベイクできます。

val requestHandler : RequestContext => HttpResponse = ???

val route : Route = 
  (requestContext) => Future(requestHandler(requestContext)) map RouteResult.Complete

onCompleteディレクティブ

onComplete ディレクティブを使用すると、ルート内のFutureを「アンラップ」できます。

val route = 
  get {

    val future : Future[HttpResponse] = ???

    onComplete(future) {
      case Success(httpResponse) => complete(httpResponse)
      case Failure(exception)    => complete(InternalServerError -> exception.toString)
    }
  }