Skip to content

Latest commit

 

History

History
473 lines (368 loc) · 23.2 KB

File metadata and controls

473 lines (368 loc) · 23.2 KB

The Play WS API

Play アプリケーションから他の HTTP サービスを呼び出したくなることがあります。Play は非同期の HTTP 呼び出しを実現する WS ライブラリ でこれをサポートしています。

WS API には、リクエストの作成とレスポンスの処理という2つの重要な部品があります。まず、GET および POST の HTTP リクエストを作成する方法について紹介し、次に WS からレスポンスを処理する方法について紹介します。最後に、よくあるユースケースを紹介します。

リクエストの作成

WS を使用するには、まず wsbuild.sbt ファイルに追加してください。

libraryDependencies ++= Seq(
  ws
)

そして、WS を利用したいコントローラやコンポーネントで WSClient への依存を宣言します。

@dependency

WSClient のインスタンスを ws と名付けたので、以下の例ではこの名前を用いることとします。

HTTP リクエストを構築するには、 WS.url() を URL を設定して呼び出します。

@simple-holder

これは WSRequest を返します。WSRequest はヘッダの設定のような様々な HTTP のオプションを設定するために使用します。メソッド呼び出しを連鎖すると、複雑なリクエストをまとめて構築できます。

@complex-holder

最後に、使用したい HTTP メソッドに対応するメソッドを呼び出します。連鎖はこれで終了し、 WSRequest のリクエストに設定した全てのオプションが使用されます。

@holder-get

すると、 Future[WSResponse] が返されます。ここで Response がサーバから返されたデータを保持しています。

認証の設定

HTTP 認証を使う必要がある場合には、ビルダーにユーザー名、パスワード、 AuthScheme を設定します。AuthScheme に適用可能なケースオブジェクトは、BASIC, DIGEST, KERBEROS, NONE, NTLM そして SPNEGO です。

@auth-request

リダイレクトの設定

もし、HTTP 呼び出しの結果が、302 や 301 のようなリダイレクトである場合には、他のメソッド呼び出しをしなくとも自動的にリダイレクトされます。

@redirects

クエリストリングの設定

パラメーターは、キーと値のタプルで設定します。

@query-string

ヘッダの設定

ヘッダは、キーと値のタプルで設定します。

@headers

もし、プレーンなテキストを特定のフォーマットで送信したいのなら、コンテントタイプを明示的に設定する必要があります。

@content-type

バーチャルホストの設定

バーチャルホストは文字列で設定します。

@virtual-host

タイムアウトの設定

リクエストにタイムアウトを設定する場合には、 withRequestTimeout を使用しミリ秒で値を設定します。 -1 を設定すると無期限になります。

@request-timeout

フォームデータの送信

フォームエンコードされたデータを POST で送信するには、postMap[String, Seq[String]] を渡してください。

@url-encoded

JSON データの送信

JSON データを送信する最も簡単な方法は、 [[JSON|ScalaJson]] ライブラリを使うことです。

@scalaws-post-json

XML データの送信

XML データを送信する最も簡単な方法は、XML リテラルを使うことです。XML リテラルは便利ですが、それほど速くはありません。効率を重視するなら、XML ビューテンプレート や JAXB ライブラリを使うことを検討してください。

@scalaws-post-xml

レスポンスの処理

Response に対する操作は Future の中でマッピングをすることで簡単に行えます。

以降の例には、いくつか共通の依存コードがあります。簡潔にするため、ここで1度だけ掲載します。

Future 上で処理を実行するときにはいつでも、暗黙的な実行コンテキストが必要となります。実行コンテキストとは Future が実行されてコールバックを行うスレッドプールのことです 。通常は、Play のデフォルトの実行コンテキストで充分でしょう。

@scalaws-context

次の例も、以降のコードで使用するシリアライゼーション、あるいはデシリアラーゼーションのためのケースクラスです。

@scalaws-person

JSON レスポンスの処理

レスポンスを JSON object として処理するには、response.json を呼び出します。

@scalaws-process-json

JSON ライブラリには、暗黙の Reads[T] をクラスに直接マッピングする [[便利な機能|ScalaJsonCombinators]] があります。

@scalaws-process-json-with-implicit

XML レスポンスの処理

レスポンスを XML リテラル として処理するには、response.xml を呼び出します。

@scalaws-process-xml

巨大なレスポンスの処理

get()post() を実行すると、レスポンスが使用可能になる前に、リクエストボディをメモリに読み込みます。数ギガバイトのファイルのような大量のダウンロードを行うと、不愉快なガベージコレクション、ひいてはアウトオブメモリーエラーを招くかもしれません。

WS では インクリメンタルなレスポンスを [[iteratee|Iteratees]] によって扱うことができます。WSRequeststream()getStream() メソッドは Future[(WSResponseHeaders, Enumerator[Array[Byte]])] を返します。enumerator には レスポンスボディが含まれています。

iteratee を使用して、レスポンスによって返却されたバイト数を数える、ちょっとした例を示します。

@stream-count-bytes

もちろん、通常はこのような方法で大きなボディを消費したくはないでしょう。より一般的な使用方法は、ボディを別の場所にストリームによって出力することです。次の例では、ボディをファイルにストリームで出力します。

@stream-to-file

レスポンスボディの送り先としては他に、このサーバーが現在処理しているレスポンスへのストリームによる出力があります。

@stream-to-result

POSTPUT は、 withMethod メソッドを明示的に呼び出す必要があります。

@stream-put

よくある例と使用方法

WS 呼び出しの連結

for 内包表記は、信頼された環境で WS の呼び出しを連結するのに適しています。起こりうる失敗を処理するには、for 内包表記と一緒に Future.recover を使用してください。

@scalaws-forcomprehension

コントローラーでの使用

コントローラーからリクエストを作成するときには、レスポンスを Future[Result] へマッピングできます。これは Play の Action.async アクションビルダーと組み合わせることで使用できます。詳細は [[非同期レスポンスの処理|ScalaAsync]] にあります。

@async-result

WSClient を使用する

WSClient は AsyncHttpClient を包むラッパーです。別々のプロファイルを指定した複数のクライアントを定義したり、モックを使用できたりして便利です。

WSによる注入を受けることなく、コードから直接 WS クライアントを定義することができます。そして、 WS.clientUrl() の際にはクライアントを暗黙的に使用することができます。

@implicit-client

NOTE: NingWSClient オブジェクトをインスタンス化した場合には、それは WS モジュールのライフサイクルに乗らないので、Application.onStop の際に自動的にはクローズされません。そのかわりに、処理が終了した際に client.close() することによりクライアントを手動でシャットダウンしなければなりません。これによって、AsyncHttpClient が内部で使用している ThreadPoolExecutor を開放します。クライアントを閉じることに失敗すると、アウトオブメモリー例外が生じるおそれがあります (特に、開発モードでアプリケーションを頻繁にリロードする場合)。

または直接、

@direct-client

あるいは、マグネットパターンを利用して、特定のクライアントを自動的に紐付けることもできます。

@pair-magnet

デフォルトでは、設定は application.conf で行われますが、設定から直接ビルダーを構築することも可能です。

@programmatic-config

内部の 非同期クライアント を使用することも可能です。

@underlying

重要な事柄が 2 点あります。WS はクライアントへのアクセス要求時に 2 つの制限があります。

  • WS はマルチパートのフォームのアップロードを直接サポートしていません。内部的なクライアントの RequestBuilder.addBodyPart を使用してください。
  • WS はストリームによるボディのアップロードをサポートしていません。この場合、AsyncHttpClient によって提供される FeedableBodyGenerator を使用してください。

WS の設定

WS クライアントの設定は、 application.conf にある以下のプロパティで行います。

  • play.ws.followRedirects: 301、および、302 でのリダイレクトにクライアントが従うかを設定します。 (デフォルトは true)
  • play.ws.useProxyProperties: システムのHTTPプロキシ設定(http.proxyHost, http.proxyPort)を使用するか設定します。 (デフォルトは true)
  • play.ws.useragent: User-Agent ヘッダーフィールドを設定します。
  • play.ws.compressionEnabled: このプロパティが true の場合 gzip/deflater によるエンコーディングを行います。 (デフォルトは false).

SSL を用いた WS の設定

HTTP over SSL/TLS (HTTPS) を使用するための WS の設定については、 [[WS SSLの設定|WsSSL]] を参照してください。

タイムアウトの設定

WS には3種類のタイムアウト設定があります。タイムアウトになると、WS リクエストが中断します。

  • play.ws.timeout.connection: リモートホストとの接続を行う最大の時間です。 ( デフォルトは 120秒 )
  • play.ws.timeout.idle: アイドル状態(コネクションは確立したが、データを待っている状態)を保持する最大の時間です。 ( デフォルトは 120秒 )
  • play.ws.timeout.request: リクエストにかかる全体の時間です(リモートホストがデータを送信中であっても、中断する可能性があります)。 ( デフォルトは 120秒 )

リクエストのタイムアウトは withRequestTimeout() を使用した接続において上書き可能です。 (“リクエストの作成”の節を参照してください。)

AsyncHttpClientConfig の設定

内部のAsyncHttpClientConfig にて、以下のような高度な設定を行うことができます。

詳しくはAsyncHttpClientConfig のドキュメントを参照してください。

  • play.ws.ning.allowPoolingConnection
  • play.ws.ning.allowSslConnectionPool
  • play.ws.ning.ioThreadMultiplier
  • play.ws.ning.maxConnectionsPerHost
  • play.ws.ning.maxConnectionsTotal
  • play.ws.ning.maxConnectionLifeTime
  • play.ws.ning.idleConnectionInPoolTimeout
  • play.ws.ning.webSocketIdleTimeout
  • play.ws.ning.maxNumberOfRedirects
  • play.ws.ning.maxRequestRetry
  • play.ws.ning.disableUrlEncoding