Single-page Application(SPA)によりフロント開発にかかる手間が膨大になっています。SPAの開発をするときに通信部分(JSONやJSONPなど)をどうすればいいのかが問題になります。解答としてはスタブAPIサーバを作成し対応します。
画面開発するためにアプリケーションサーバを構築するのは時間の無駄ですのでgruntタスクにモックサーバを構築し簡単実装を行いましょう。 「本物の」APIサーバを使う場合は向きを変えることで簡単に結合テストできますし、CIを使うときはもちろんモックサーバでのテストになりますのでモックAPIサーバは活用するのが良いと考えます。
モックAPIサーバ
gruntでモック用APIサーバを立ち上げるためのプラグインとして有名なものとして2つ存在します。
- grunt-easymock
- grunt-stubby
easymockはnode-easymockをgruntプラグイン化したものです。studdyはstubby4nodeをgruntプラグイン化したものです。どのような場合を使っても
- grunt-connect-proxy
は必要になります。nodeでサーバを立ててますのでプロキシサーバを使いモックサーバへリダイレクトをします。
こうすることでbackbone等でJSON等の開発が簡単に行えます。
grunt-connect-proxyの構築
モックAPIサーバを構築する前にプロキシサーバを構築します。プロキシサーバにはgrunt-connect-proxyを利用します。
$ npm install grunt-connect-proxy --save-dev
でインストールします。次にgruntタスクへの追加を行います。
connect: { options: { port: SERVER_PORT, hostname: 'localhost' }, livereload: { ・・・ }, /* プロキシサーバの設定 */ proxies: [{ context: '/mockapi', host: 'localhost', port: '3000', https: false, changeOrigin: false }],
こうすることでプロキシサーバを経由してローカルにある3000ポートのAPIサーバにアクセスすることが可能となります。
grunt-easymockの構築
モックサーバの一つeasymockを利用します。easymockはgruntプラグインを使わなくてもインストール可能です。
$ npm install -g easymock $ easymock Server running on http://localhost:3000 Documentation at: http://localhost:3000/_documentation/ Logs at: http://localhost:3000/_logs/
これではgruntを利用する目的が半減しますのでgrunt-easymockを使います。
$ npm install grunt-easymock --save-dev
Gruntfile.jsを修正します。
grunt.initConfig({ yeoman: yeomanConfig, /* easymockの設定 */ easymock: { mockapi: { options: { port: 3000, path: 'server/api-server', config: { routes: [ '/users/:id' ] }, }, }, },
ここで「easymock」の次の「mockapi」キーワードが重要です。こことproxyで定義したcontextが一致します。期待するURLは
/mockapi/users/1
です。easymockをタスクに登録します。
grunt.task.run([ 'clean:server', 'coffee:dist', 'createDefaultTemplate', 'handlebars', 'compass:server', 'configureProxies', 'connect:livereload', 'open', 'easymock', 'watch' ]);
次に使用するデータを作ります。easymockのディレクトリパスを「server/api-server」とし、コンテキストパス「mockapi」、パス「users/1」ですのでディレクトリを設定ファイル「config.json」を次のように定義します
1_get.jsonはgetメソッドでのデータ取得を意味しています。内容は
server/api-server/mockapi/users/1_get.json
[ { "id": 1, "user": "john", "message": "hello" }, { "id": 2, "user": "bob", "message": "Hi!" }, { "id": 3, "user": "mike", "message": "good bye." } ]
http://localhost:3000/mockapi/users/1
をブラウザで実行し1_get.jsonの内容が表示できたらまずは成功です。gruntタスクを実行し実際にアプリケーションを動かして最終的に確認します。
grunt-stubbyの構築
easymock同様、nodeモジュールとしてインストールし手動にて実行できますが、せっかくですのでgruntタスクに登録します。
$ npm install grunt-stubby --save-dev
stubbyの設定は
grunt.initConfig({ yeoman: yeomanConfig, /* stubbyの設定 */ stubby: { stubsServer: { options: { callback: function (server, options) { server.get(1, function (err, endpoint) { if (!err) console.log(endpoint); }); }, stubs: 3000, tls: 8443, admin: 8010 }, // note the array collection instead of an object files: [{ src: [ 'server/stubby/*.yaml' ] }] } },
stubsがスタブとしての待ち受けポートです。スタブのデータは「server/stubby/*.yaml」に定義します。具体的には
- request: url: ^/mockapi/users/1$ method: [GET, POST] response: - status: 200 headers: content-type: application/json file: server/api-server/mockapi/users/1_get.json
リクエストとして待ち受けるurlは「/mockapi/users/1」でレスポンスデータは先ほどと同じく「server/api-server/mockapi/users/1_get.json」です。gruntタスクに加えます。
grunt.task.run([ 'clean:server', 'coffee:dist', 'createDefaultTemplate', 'handlebars', 'compass:server', 'configureProxies', 'connect:livereload', 'open', 'stubby', 'watch' ]);
これで設定は完了です。
http://localhost:3000/mockapi/users/1
をブラウザで実行し1_get.jsonの内容が表示できたらまずは成功です。gruntタスクを実行し実際にアプリケーションを動かして最終的に確認します。
最後に
easymockはsqliteを内部的に使っています。CentOSでビルドするとライブラリlibc.so.6(GLIBC_2.14)がないというエラーが発生し利用することができません。クライアント開発では問題ないがCIでは利用できないという本末転倒なところです。別のOSを利用するかstubbyを使うか時を待つかです。
モック開発でeasymockかstubbyかどちらが優れているかは明確にはできませんがSingle-page Applicationを構築する場合は使うべきと考えています。わざわざJavaが実行するAPIサーバを各クライアントに構築するのは。。。