2つのWeb APIがあり、1つめのAPIを呼び出して得た結果を使って次のAPIを呼び出す必要があるとします。
ScalaではHTTP通信を行うためのライブラリとしてDispatchというものがあるのですが、このライブラリはノンブロッキングI/Oを使っており、Futureベースのインターフェースを備えています。
例えばGETメソッドでの通信は以下のようにして行うことができます。戻り値はEither
になっており、エラーの場合はLeft
でThrowable
を返す便利仕様ですが、通信に失敗した場合もonSuccess
で処理しなくてはいけないのはやや紛らわしいかもしれません。
import dispatch._, Defaults._
def get(endpoint: String): Future[Either[Throwable, String]] = {
val request = url(endpoint).GET
Http(request OK as.String).either
}
// こんな感じで使える
get("http://www.yahoo.co.jp/").onSuccess {
case Left(t) => t.printStackTrace()
case Right(s) => println(s)
}
このライブラリを使って2つのWeb APIをシリアルに呼び出す処理を実装してみます。
コールバックで書くとこんな感じ。シンプルでわかりやすいですが、処理が増えるとコールバック地獄になることが目に見えています。
post("http://localhost:8080/get_id").onSuccess {
case Right(id) => post("http://localhost:8080/recover/" + id)
}
こんな場合にはmap
を使います。これならチェーンさせるリクエストが増えてもフラットに記述することができます。
post("http://localhost:8080/get_id").map { id =>
post("http://localhost:8080/recover/" + id)
}