FuelPHP の Rest コントローラの使い方とデフォルトフォーマットの変更の仕方


## FuelPHP のバージョン

1.7.3

## Rest コントローラとは

Rest コントローラは Base コントローラを継承したもので、RESTful のサポートが組み込まれている。これは、API を簡単に構築をすることが出来る。
これはWebAPIなどでjsonやxml、csv等を返すサービスを作る場合にとても便利な機能が満載なのだ。

## Rest コントローラの使い方

### コントローラの作成

すべてのコントローラと同様に、fuel/app/classes/controllerディレクトリ内にクラスを作成する。 それらは Controller_Rest クラスを継承し、"Controller_" というプレフィックスを付ける。

```fuel/app/classes/controller/api.php
<?php
class Controller_Api extends Controller_Rest
{
    // HTTP メソッドが GET の場合
    public function get_list()
    {
        $list = array(
            'foo' => Input::get('foo'),
            'baz' => array(
                1, 50, 219
            ),
            'empty' => null
        );
        
        // $this->responseに配列として設定する
        return $this->response($list,200);
    }
    // HTTP メソッドが POST の場合
    public function post_list()
    {
        $list = array(
            'foo' => Input::get('foo'),
            'baz' => array(
                1, 50, 219
            ),
            'empty' => null
        );
        
        // $this->responseに配列として設定する
        return $this->response($list,200);
    } 
}
```

### cURL コマンドで出力

#### get

##### xml

```
$ curl http://example.com/api/list.xml?foo=get
<?xml version="1.0" encoding="utf-8"?>
<xml><foo>get</foo><baz><item>1</item><item>50</item><item>219</item></baz><empty/></xml>

```

##### json

```
$ curl http://example.com/api/list.json?foo=get
{"foo":"get","baz":[1,50,219],"empty":null}
```

#### post

##### xml

```
$ curl -d foo=post http://example.com/api/list.xml
<?xml version="1.0" encoding="utf-8"?>
<xml><foo>post</foo><baz><item>1</item><item>50</item><item>219</item></baz><empty/></xml>
```

##### json

```
$ curl -d foo=post http://example.com/api/list.json
{"foo":"post","baz":[1,50,219],"empty":null}
```


### HTTP メソッド

Rest コントローラにおいても "action_" というプレフィックスのメソッドは、上記のように "post_" などという HTTP メソッドをプレフィックスとしたメソッドの代わりになる。 HTTP メソッドに当てはまるプレフィクスのメソッドがない場合、"action_" プレフィクスのメソッドが代わりに呼び出される。 

* GET
* POST
* PUT
* DELETE
* PATCH

### サポートされるフォーマット

* xml
* json
* csv
* html
* php
* serialize

## デフォルトフォーマットの変更

REST コントローラは、Core の設定ファイルである `fuel/core/config/rest.php` でグローバルに設定されており、既にデフォルト値が入力されている。拡張子を省略した際はこの設定ファイルのデフォルト値が有効となる。設定ファイルを上書きするには、アプリケーションの設定ディレクトリに同名の設定ファイルを追加して、 設定したい値に変更すれば良い。 これによって、Core の設定が上書きされるが、上書きされなかった設定は元の値が保持される。

例えば、json をデフォルトフォーマットにしたい場合は、`fuel/core/config/rest.php` を `fuel/app/config/rest.php` にコピーし、 `default_format` キーの値を 以下のように `xml` から `json` に変更する。

```diff:fuel/app/config/rest.php
-	'default_format' => 'xml',
+	'default_format' => 'json',
```

デフォルトフォーマットの変更完了…！とは行かない。  
この設定までだと `ignore_http_accept` キーの値がデフォルトの `false` のままなので、HTTP ヘッダ情報の HTTP_ACCEPT に含まれる MIME タイプが Rest_Controller の `$_supported_formats` 配列内に存在すると `default_format` キーの値より優先されてしまう。

```fuel/core/controller/rest.php
	protected $_supported_formats = array(
		'xml' => 'application/xml',
		'rawxml' => 'application/xml',
		'json' => 'application/json',
		'jsonp'=> 'text/javascript',
		'serialized' => 'application/vnd.php.serialized',
		'php' => 'text/plain',
		'html' => 'text/html',
		'csv' => 'application/csv',
	);
```

HTTP_ACCEPT がフォーマットの判定に使われないようにするには `ignore_http_accept` キーの値を `true` に変更する。

```diff:fuel/app/config/rest.php
-    'ignore_http_accept' => false,
+    'ignore_http_accept' => true,
```

### cURL コマンドで出力

拡張子を省略してアクセス。

#### get

```
$ curl http://example.com/api/list?foo=get
{"foo":"get","baz":[1,50,219],"empty":null}
```

#### post

```
$ curl -d foo=post http://example.com/api/list
{"foo":"post","baz":[1,50,219],"empty":null}
```

## 参考文献

* [Rest コントローラ - 概要 - FuelPHP ドキュメント](http://fuelphp.jp/docs/1.7/general/controllers/rest.html#/formats "Rest コントローラ - 概要 - FuelPHP ドキュメント")
* [FuelPHP：Rest_Controllerの拡張子を省略した時のフォーマットを変更する | memocon](http://www.crossl.net/blog/set_rest_controler_def_value/ "FuelPHP：Rest_Controllerの拡張子を省略した時のフォーマットを変更する | memocon")