CakePHP2 REST 設定

sencha用にCakePHP2のREST設定をしてみました。
※作成時のCakePHPバージョンは 2.5.2 となります。

■データベースの準備

```lang:postgresql
CREATE TABLE todos
(
  id serial NOT NULL,
  title character varying(32) NOT NULL,
  require smallint NOT NULL,
  deadline date NOT NULL,
  CONSTRAINT todos_pkey PRIMARY KEY (id)
)
```

■CakePHP 新しいプロジェクト作成(hoge)

```lang:sh
Vendor/bin/cake bake project hoge 
cd hoge
Console/cake bake 
***
```

■vi Config/database.php

```lang:php
<?php
class DATABASE_CONFIG {
        public $default = array(
                'datasource' => 'Database/Postgres',
                'persistent' => false,
                'schema' => 'public',
                'host' => '192.168.***.***',
                'port' => 5432,
                'login' => 'user',
                'password' => 'password',
                'database' => 'hoge',
                'encoding' => 'UTF-8'
        );
}
?>
```

■とりあえずはスカフォルディングして動作確認


```lang:sh
Console/cake bake all
```

※ブラウザで確認
http://192.168.***.***/todos/
２・３データを登録しておく。

■ルーターの設定( vi Config/routes.php  )

下記を require CAKE . 'Config' . DS . 'routes.php'; の前に記述する。

```lang:php
/**
* REST Router
*/
Router::parseExtensions('json');
Router::resourceMap(array(
array('action' => 'index', 'method' => 'GET', 'id' => false),
array('action' => 'view', 'method' => 'GET', 'id' => true),
array('action' => 'add', 'method' => 'POST', 'id' => false),
array('action' => 'edit', 'method' => 'PUT', 'id' => true),
array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
));

Router::connect(
"/:controller",
array("action" => "add", "[method]" =>'POST'),
array("id" => "[0-9]+")
);

Router::connect(
"/:controller/:id",
array("action" => "view", "[method]" =>'GET'),
array("id" => "[0-9]+")
);

Router::connect(
"/:controller/:id",
array("action" => "view", "[method]" =>'OPTIONS'),
array("id" => "[0-9]+")
);

Router::connect(
"/:controller/:id",
array("action" => "delete", "[method]" =>'DELETE'),
array("id" => "[0-9]+")
);

Router::connect(
"/:controller/:id",
array("action" => "edit", "[method]" =>'PUT'),
array("id" => "[0-9]+")
);

```

■コントローラの設定  ( vi Controller/AppController.php )

今回は全てのモデルをREST扱いにする。
モデルごとに設定するならば各コントローラに記述する。

```lang:php
<?php
/**
 * Application level Controller
 *
 * This file is application-wide controller file. You can put all
 * application-wide controller-related methods here.
 *
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.Controller
 * @since         CakePHP(tm) v 0.2.9
 */

App::uses('Controller', 'Controller');

/**
 * Application Controller
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @package		app.Controller
 * @link		http://book.cakephp.org/2.0/en/controllers.html#the-app-controller
*/
class AppController extends Controller {

	public $components = array('RequestHandler');

	public function beforeFilter()
	{
		if ( $this->request->is('options') ) {
			$this->_set_json( 'OK' );
		}
		$this->response->header('Access-Control-Allow-Origin: *');
		$this->response->header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
		$this->response->header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
	}


	public function index()
	{
		if ( $this->request->is('options')==false ) {
			$this->_set_json( $this->{ $this->modelClass }->find('all') );
		}
	}


	public function view($id=null)
	{
		if ( $this->request->is('options')==false ) {
			$this->_set_json( $this->{ $this->modelClass }->findById($id) );
		}
	}


	public function add()
	{
		if ( $this->request->is('options')==false ) {
			$this->request->data['id']=null;
			$this->{ $this->modelClass }->create();
			$results = $this->{ $this->modelClass }->save($this->request->data);
			if ( $results ) {
				$results = 'Saved';
			} else {
				$results = 'Error';
			}
			$this->_set_json( $results );
		}
	}


	public function edit($id=null)
	{
		if ( $this->request->is('options')==false ) {
			$this->{ $this->modelClass }->id = $id;
			$results = $this->{ $this->modelClass }->save($this->request->data);
			if ( $results ) {
				$results = 'Saved';
			} else {
				$results = 'Error';
			}
			$this->_set_json( $results );
		}
	}


	public function delete($id=null)
	{
		if ( $this->request->is('options')==false ) {
			$results = $this->{ $this->modelClass }->delete( $this->request->params['id'] );
			if ( $results ) {
				$results = 'Saved';
			} else {
				$results = 'Error';
			}
			$this->_set_json( $results );
		}
	}


	function _set_json($results)
	{
		$this->set(array(
				'results' => $results,
				'_serialize' => array('results')
		));
	}


}
```

■コントローラの中身を削除 ( vi Controller/TodosController.php ) 

```file:php
<?php
App::uses('AppController', 'Controller');
class TodosController extends AppController {
}
```

■View/Todo 削除

```lang:sh
rm -rf View/Todos/
```

■ブラウザにて動作確認

以下の様なURLにて希望の書式でデータが戻ればOKです。

http://192.168.***.***/todos.json
http://192.168.***.***/todos.xml
http://192.168.***.***/todos/2.json

以上