今回は前回まで作っていたスクリプトをまとめて、Dispatchを使ってTumblrのAPIを叩くライブラリを作りたいと思います。
前回まではScalasスクリプトでコードを書いていましたが、今回からはsbtを導入していきいたいと思います。
sbtはAnt、Mave、Ivyなどと同じビルドツールなんですが、以下の特徴があります。
1は、MavenとIvyのいいところ取りと言ったら言い過ぎかもしれませんが、 全体的には簡単に書けるようになったMavenという感じです。
2は、XMLで書かなくていいというのは非常に嬉しいです。 僕はテキストエディタ派なのでタイピングの量がかなり減りますからね。
3は、Mavenでも規約を使うことで設定を減らしていたのですが、sbtはさらに徹底されている感じです。
どのくらい最小限かというと、実は設定ファイルを書く必要すらありません。
空のフォルダにHelloWorld.scalaだけを作ってsbt runと打ってみると動くくらいです。
実際は依存するライブラリを書かなきゃいけなかったりするので、
こういうことはないのですが、本当に必要なことだけを書けばいいという感じです。
より詳しいことはsbtのドキュメントを翻訳してくださった方がいらっしゃるのでそちらを見てください。
dispatch-tumblr
├── build.sbt
└── src
├── main
│ └── scala
│ └── Tumblr.scala
└── test
└── scala
└── TumblrSpec.scala
ディレクトリ構成自体はMavenから引き継いだ規約によるもので、ファイルについての設定はまったく必要ありません。
作るファイルはbuild.sbt、Tumblr.scala、TumblrSpec.scalaの三つだけです。
build.sbtはsbtの設定ファイル。
Tumblr.scalaはライブラリ本体。
TumblrSpec.scalaはspecsというScalaのテストフレームワークを使ったテストコードです。
僕はよくこういうファイル三つだけの構成のプロジェクト作ります。
あと、プラグイン用のbuild.sbtを付け加えるくらいで。
簡単に作れるのがsbtプロジェクトのいいところです。
各項目簡単に説明します
ライブラリを作るというと、APIをどう設計するのかが悩ましいところ。 でも今回はTwitter用の n8han/dispatch-twitter というライブラリが先にあるので、これを真似していきたいと思います。
方針としては以下の三つです。
1は、最低限やらないといけないことですね。
2は、DispatchのBuilderという仕組みを使います。まんまGoFのビルダーパターンです。
3は、前に紹介したdispatch-jsonを使います。
では、ソースコードを見ていきます。
ざっと説明していきます。
AuthオブジェクトはOAuth、xAuthの処理がまとめられています。単にメソッド化しただけです。
BlogオブジェクトはTumblr APIのBlogメソッドに対応しています。
Tumblr API v2リファレンス和訳(原文:2011/08/07 19:11:23時点) - Walrus, Googling.
「小手調べ編」で使ったのがBlogオブジェクトのavatarメソッド。
「dispatch-json編」で使ったのがinfoメソッド。
それぞれ元のスクリプトからコードが移植されています。
問題はpostメソッドですね。「xAuthで投稿編」で使われたAPIですが、
今回はクエリーの組み立てにBuilderという仕組みが使われています。
productメソッドでHandlerを返す処理を書いておくと、implicit conversionを使ってHandlerに変換されます。
使い方は後でサンプルを見てください。
次に、このBlogオブジェクトはJsというトレイトを継承しています。
「dispatch-json編」で使ったJSONを分解するためのメソッドが使えるようになります。
これでレスポンスの構造に合わせて分解しやすいようなメソッドを用意しておきます。
しかし、BlogオブジェクトがJSONの面倒まで見るというのは、dispatch-twitterの方針に乗っ取ってるんですが、正直微妙な気がしますね。
TwitterとTumblrのAPIの違いからくるものかもしれませんが、リクエストを作るのと、レスポンスの処理は別のものなので、一緒にしないほうがいい気がします。
でも今回は前例に沿ってこの方針でいきます。
今回新しくダッシュボードの情報を取得するメソッドを追加しました。テスト用コードなので、全然埋めてないんですが。
Blogオブジェクトと同じように、UserオブジェクトはBuilderを使ったリクエストを作る処理で、PostオブジェクトはレスポンスのJSONを解析する処理です。
specsはScalaのBDDテストフレームワークなんですが、僕は気軽にサンプルコード書く感じで使ってます。 だから全然正しい使い方じゃないと思います。
詳しくはこちらをどうぞ
複雑なことはやってないので詳しい説明は省きますが、Afterという仕組みで共通の処理を括り出せます。
大量にテストを書くときには便利です。同じようなものにBeforeとBeforeAfterというものがあります。
sbtで作ったライブラリを他のプロジェクトから使う場合は、sbt publish-localコマンドを使います。
このコマンドを使うとライブラリがIvyのローカルリポジトリにインストールされ、sbtから使えるようになります。
サンプルコードを動かす前にやっておきましょう。
ポイントを説明します。
libraryDependencies += "com.github.hexx" %% "dispatch-tumblr" % "0.0.1"
使うライブラリにbuild.sbtに書いたorganization、name、versionの三つを指定します。
dispatch本体などは芋づる式に依存関係が解決されるので書かなくても大丈夫です。
今回はdispatchも直接使っているので、書いたほうが行儀がいいかもしれません。
val access_token = http(Auth.access_token(consumer, username, password))
xAuthを使ってAccess Tokenを取得する処理です。 Dispatchの謎の呪文wのような処理が隠蔽されてます。
val res = http(User.dashboard(consumer, access_token) posttype "text" limit 5)
これはダッシュボードからテキストタイプのポストを5つ取ってくるという処理です。 ビルダーはこういうふうに使われます。
res map Post.title foreach println
取ってきたダッシュボードのポストのタイトルをプリントする処理です。
Post.titleはレスポンスからタイトルを取り出す関数になります。
これをmapしてやれば、レスポンスからタイトルのリストが取り出され、それをforeachを使って順番にプリントしています
Scalaのメソッドチェーンはこういう形式で書くことも多いです。
Scalaに慣れてない人だと一見何をやってるのかわからないかもしれませんが、
Scalaで.と()を省略できるのは1引数のメソッド(要するに二項演算子)だけと覚えておくと、簡単に読めるようになります。
以上説明してきたライブラリはgithubに上げてあります。
APIが全然足りてないんですが、TumblrのAPIの数は少ないのでそのうち全部埋めておこうと思います。
今回の記事で、ScalaはLL言語ではないけど、sbtによってすごく気楽に開発してる感じが伝わればいいかなと思います。