LoginSignup
56

More than 5 years have passed since last update.

AngularJSでバックエンドの疑似APIサーバ(スタブ)を構築する

Posted at

WEBサービスを実現する場合、フロントエンドからバックエンドのAPIサーバにアクセスすることが多いと思いますが、バックエンド側がまだ開発途中であったりすると、代替としてNode.js等でスタブのアプリケーションを作ったり、または固定のJSONファイルを作ったりと、割と手間がかかってしまいます。

今回、ためしに AngularJS の ngMockE2E を利用して、擬似的なAPIサーバを構築してみたので、その方法を紹介します。

前提

  • Yeomanで構築したAngularJS開発環境が前提です。

  • 別途 ngMockライブラリをインストール場合も、Bower を使えば簡単にできます。

    • $ bower install angular-mocks

ngMockを使う準備

①index.htmlからngMockのJSファイルをロード

app/index.html
<script src="bower_components/angular-mocks/angular-mocks.js"></script>

②ルートモジュールにngMockE2Eを追加

app/scripts/app.js
'use strict';

angular.module('ngMockTestApp', [
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'ngRoute',
+  'ngMockE2E'
])
  .config(['$routeProvider', function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  }]);

これで準備は完了です。

疑似APIサーバの処理を書く

  • 先程と同じ app.js に、.run 以降を追記してみます。
    • 面倒なのでこうしてますが、本当はファイルを分けた方がいいです。
app/scripts/app.js
'use strict';

angular.module('ngMockTestApp', [
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'ngRoute',
  'ngMockE2E'
])
  .config(['$routeProvider', function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  }])
  .run(['$httpBackend', function ($httpBackend) {

    $httpBackend.whenGET(/^views\//).passThrough();

    var sample = [
      {
        "id": "1",
        "name": "山田"
      },
      {
        "id": "2",
        "name": "鈴木"
      }
    ];

    $httpBackend.whenGET('data/sample.json?hoge=1').respond(200, sample, {});

    $httpBackend.whenGET('data/sample.json?hoge=2').respond(function(method, url, data, headers) {
            return [200, sample, {}];
    });

  }])
;

動作確認

ここは何でもいいのですが、APIを叩く処理を書きます。

まず、APIにアクセスするFactoryを作って、

app/scripts/services/data.js
'use strict';

angular.module('ngMockTestApp')
  .factory('JsonData', function ($http) {

    return {

      getSampleData: function () {

        return $http.get('data/sample.json?hoge=1')

          .success(function(data, status, headers, config) {

            return data;

          });

      }

    }

  })
;

Controllerから呼び出し、

app/scripts/controllers/main.js
'use strict';

angular.module('ngMockTestApp')
  .controller('MainCtrl', ['$scope', 'JsonData', function ($scope, JsonData) {

    JsonData.getSampleData().then(function(res){

      $scope.items = res.data;

    });

  }])
;

Viewで描写します。

app/views/main.html
<!-- 対応する Controller は app.js の $routeProvider で定義済み -->
<li ng-repeat="item in items">
  {{item.id}} - {{item.name}}
</li>

結果はこんな感じ。表示されました!

スクリーンショット 2014-05-13 15.06.07.png

疑似APIサーバの処理をみてみる

  .run(['$httpBackend', function ($httpBackend) {

    $httpBackend.whenGET(/^views\//).passThrough();

    var sample = [
      {
        "id": "1",
        "name": "山田"
      },
      {
        "id": "2",
        "name": "鈴木"
      }
    ];

    $httpBackend.whenGET('data/sample.json?hoge=1').respond(200, sample, {});

    $httpBackend.whenGET('data/sample.json?hoge=2').respond(function(method, url, data, headers) {
            return [200, sample, {}];
    });

  }])

全ての HTTPアクセスがこのロジックを経由します。
で、ここに全てのHTTPアクセスについて定義しないとエラーになるので、注意が必要です。
(正規表現はつかえます。)

.passThrough()は何もしない、という意味です。テンプレートのアクセスもHTTP経由なので、「URLが views/ で始まる場合は何もしない」というふうに記載しています。

whenGET でURLを定義し、対応するレスポンスを .respond に記載します。今回は2パターンを記載してみました。

上のパターンは、単純に用意されたJSONデータをレスポンンスしています。

下のパターンは、JavaScriptでいろいろ処理させてからレスポンンスさせるパターンです。
この例だと、結局JSONをレスポンスしているだけですが、判定処理とか動的なJSONファイルの生成処理がここに書けるわけです。

ほか

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
56