albatrosary's blog

Azure と Angular と Wercker CI とか

Single-page Application(SPA)でeasymock or stubbyを使ってJSON簡単開発

Single-page Application(SPA)によりフロント開発にかかる手間が膨大になっています。SPAの開発をするときに通信部分(JSONJSONPなど)をどうすればいいのかが問題になります。解答としてはスタブAPIサーバを作成し対応します。

 

画面開発するためにアプリケーションサーバを構築するのは時間の無駄ですのでgruntタスクにモックサーバを構築し簡単実装を行いましょう。 「本物の」APIサーバを使う場合は向きを変えることで簡単に結合テストできますし、CIを使うときはもちろんモックサーバでのテストになりますのでモックAPIサーバは活用するのが良いと考えます。

モックAPIサーバ

gruntでモック用APIサーバを立ち上げるためのプラグインとして有名なものとして2つ存在します。

  • grunt-easymock
  • grunt-stubby

easymockはnode-easymockをgruntプラグイン化したものです。studdyはstubby4nodeをgruntプラグイン化したものです。どのような場合を使っても

  • grunt-connect-proxy

は必要になります。nodeでサーバを立ててますのでプロキシサーバを使いモックサーバへリダイレクトをします。

 

f:id:albatrosary:20140206145308p:plain

 

 

こうすることで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」を次のように定義します

f:id:albatrosary:20140206152823p:plain

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サーバを各クライアントに構築するのは。。。