AngularJSからRestfulなリクエストを送信

CakePHPのrestfulインタフェースにAngularJSからリクエストしてデータを取得

CakePHPで効率的にrestful APIを開発

AngularJSでCRUD操作を行うアプリケーションを開発するにはどうすればよいか?

本エントリーでは、

  • バックエンドにCakePHP
  • フロントエンドにAngularJS

を利用した開発ノウハウをCRUD操作の「Read」に焦点をあてて書いてみたい。

バックエンド側については、CakePHPで効率的に開発を進めることができる。具体的には公式ドキュメントの以下のURLを参考にrestful apiを組むことができる。

http://book.cakephp.org/2.0/ja/development/rest.html

RecipesController.phpを作成し、以下のアクションを作成した。

class RecipesController extends AppController {

    public $components = array('RequestHandler');

    public function index() {
        $recipes = $this->Recipe->find('all');
        $this->set(array(
            'recipes' => $recipes,
            '_serialize' => array('recipes')
        ));
    }
}

簡略化のためにindexアクションのみ(Readのみ)を作成することにした。

Readするデータが必要になるので、recipesテーブルを以下のSQLのように定義する。

CREATE TABLE IF NOT EXISTS `recipes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` text COLLATE utf8_unicode_ci,
  `body` text COLLATE utf8_unicode_ci,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;

INSERT INTO `recipes` (`id`, `title`, `body`, `created`, `modified`) VALUES
(1, 'test recipe', 'recipe content', '2014-02-19 11:43:20', '2014-02-19 11:43:20'),
(2, 'test recipe2', 'recipe content2', '2014-02-19 11:43:40', '2014-02-19 11:43:40');

最後にroutes.phpに以下を追記する。

Router::mapResources("recipes");
Router::parseExtensions();

バックエンド側の準備が完了したのでブラウザで、

/recipes.json

にアクセスしてみる。

{
    "recipes": [
        {
            "Recipe": {
                "id": "1",
                "title": "test recipe",
                "body": "recipe content",
                "created": "2014-02-19 11:43:20",
                "modified": "2014-02-19 11:43:20"
            }
        },
        {
            "Recipe": {
                "id": "2",
                "title": "test recipe2",
                "body": "recipe content2",
                "created": "2014-02-19 11:43:40",
                "modified": "2014-02-19 11:43:40"
            }
        }
    ]
}

json形式でデータを取得することができた。

なお、本エントリーに書くにあたり以下のURLでアクセスできるようにWindowsローカルサーバを構成して確認した。

restful-cakephp.local/recipes.json

AngularJSからrestful APIを利用する

CakePHPを用いたバックグラウンド側のAPIの準備が整ったのでAngularJS側からリクエストを送信する。APIの呼び出し部分のJSは以下のようにした。

function Get_request($scope, $http) {
    $http.get('http://restful-cakephp.local/recipes.json').
        success(function(data) {
            $scope.recipes = data.recipes;
        });
}

Get_requestという関数を一つ作成し、その中でCakePHPのRestful APIをリクエストし結果を$scopeに格納し、テンプレート側で利用可能な状態にしている。

次にテンプレート側

<!doctype html>
<html ng-app>
	<head>
		<title>AngularJS requests CakePHP restful API</title>
		<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
    		<script src="get_request.js"></script>
	</head>

	<body>
		<div ng-controller="Get_request">
			<ul>
			    <li ng-repeat="recipe in recipes">[{{recipe.Recipe.id}}]{{recipe.Recipe.title}}</li>
			</ul>
		</div>
	</body>
</html>

liにng-repeatを定義して繰り返し処理を行っている。

  • ng-app
  • ng-controller
  • ng-repeat

AngularJSで利用頻度の高い3つのディレクティブを利用してテンプレート側を組んでみた。Get_request関数でバックエンド側のAPIを呼び出しているが、以下のように書くことも可能。

controllers.jsにコントローラをまとめる

AngularJSを構造化するために、アプリケーションの本体app.jsとコントローラcontroller.jsに分離します。app.jsを以下のように定義します。

(function() {
    var ajs = angular.module('myApp', ['myApp.controllers']);
}());

そして、controller.jsは以下のようにしました。

(function() {
    var ajs = angular.module('myApp.controllers', []);
    ajs.controller('AppCtrl', function($scope, $rootScope, $http) {
        $rootScope.appUrl = "http://restful-cakephp.local";
    });

    ajs.controller('GetRequestCtrl', function($scope, $rootScope, $http) {
        var load = function() {
            console.log('load中です');
            $http.get($rootScope.appUrl + '/recipes.json')
                    .success(function(data, status, headers, config) {
			$scope.recipes = data.recipes;
                    });
        }

        load();
    });
}());

テンプレート側のng-controllerの定義の仕方によりますが、AppCtrlでアプリケーション全体で処理する部分を書き、GetRequestCtrlのような個別の処理を以後並列に書いていくイメージです。

テンプレート側は以下のように変更しました。

<!doctype html>
<html ng-app="myApp">
	<head>
		<title>AngularJS requests CakePHP restful API</title>
		<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
<script src="app.js"></script>
    		<script src="controllers.js"></script>
	</head>

	<body ng-controller="AppCtrl">
		<div ng-controller="GetRequestCtrl">
			<ul>
			    <li ng-repeat="recipe in recipes">[{{recipe.Recipe.id}}]{{recipe.Recipe.title}}</li>
			</ul>
		</div>
	</body>
</html>

コードの構造化に伴い、

  • ng-app=”myApp”
  • ng-controller=”AppCtrl”

のようにアプリケーション名とbodyタグにAppCtrlを指定している点が異なっています。コードを構造化すると開発方法のイメージがより具体的に考えらえるようになります。

Restfulとは?

今回のエントリーでは、データを取得するだけにしましたが、実際のCRUD処理では、

  1. データの取得
  2. 追加
  3. 変更
  4. 削除

の処理が必要になります。

上に載せたコードでは、コントローラ側からAngularJSのgetリクエストを送信していますが、データを追加する際にはPostリクエスト、変更する場合はPutリクエストを利用して、バックエンド側にリクエストを送信すれば、CakePHP側で適切にリクエストの処理を判別しデータが処理されます。

参考

Webエンジニアブログにコメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

AngularJSからRestfulなリクエストを送信の記事にコメントを投稿