Posted at

PlayFrameworkで他のWebAPIと連携をするやり方


概要

WeekendEngineerというグループの中で9月にPlayFrameworkを使ったTwitterツールの開発をしました。レスポンスが遅くて辛い。。。

GitHub/ochiai_auto_tweet

○○っぽいツイートジェネレータ.gif

その際にPythonを使ったWebAPIと連携をするためにWSClientを使いました。備忘録のためにもPlayFramework2.6のWSClientを使って外部のWeb APIとやりとりをする方法を残しておきます。


やりたいこと


  • 以下の仕様のAPIを叩く。

url
response

generate_tweet/:twitter_id
{"tweet": "texttext..."}


  • 生成されたテキストを取得する


実装方法


コード


client.TweetGeneratorClient.scala


@Singleton
class TweetGeneratorClient @Inject()(ws: WSClient) extends ITweetGeneratorClient {
def generateTweet(twitterId: String): Tweet = {
val request: WSRequest = ws.url("http://127.0.0.1:5000/generate_tweet/" + twitterId)
val futureResult: Future[String] = request.get().map{
response => (response.json \ "tweet").as[String]
}
val tweetText: String = Await.result(futureResult, Duration.Inf)
return Tweet.createNewTweet(tweetText)
}
}



解説


wsclientにAPIのURLを設定

WSClientクラスのインスタンスをDIします。


client.TweetGeneratorClient.scala

@Singleton

class TweetGeneratorClient @Inject()(ws: WSClient) extends ITweetGeneratorClient {
}


ws#url(url: String)の引数にAPIのURLを指定します。


client.TweetGeneratorClient.scala

  def generateTweet(twitterId: String): Tweet = {

val request: WSRequest = ws.url("http://127.0.0.1:5000/generate_tweet/" + twitterId)
}


レスポンス(JSON)から文字列を抽出

request#get()メソッドで取得したresponseのjsonから、"tweet"というキーの値を取得します。

(response.json \ "key名").as[String]で、指定したキーを文字列で抜き出せるみたいです。


client.TweetGeneratorClient.scala

  def generateTweet(twitterId: String): Tweet = {

val request: WSRequest = ws.url("http://127.0.0.1:5000/generate_tweet/" + twitterId)

val futureResult: Future[String] = request.get().map{
response => (response.json \ "tweet").as[String]
}
val tweetText: String = Await.result(futureResult, Duration.Inf)
return Tweet.createNewTweet(tweetText)
}



ちなみに

以下のコードは{person: {name: ""}}のようなネストしたJSONから文字列を取得する例です。

(公式ドキュメントより拝借)

val futureResult: Future[String] = ws.url(url).get().map {

response =>
(response.json \ "person" \ "name").as[String]
}

他にもJavaでおなじみJacksonのscala-moduleも使えます。


最後に

これでPluginの出ていないような外部APIを叩いて、レスポンスを受け取ることができますね。Webサービスから提供されるAPIのレスポンスは複雑なJSON配列であることが珍しくないので、jackson-module-scalaにも挑戦してみようかなと思います。


参考文献

Play2公式ドキュメント-ScalaWS