RESTfulリソース処理

表現状態転送(REST)は、分散アプリケーションのためのアーキテクチャスタイルであり、Roy Fieldingが2000年の博士論文「Architectural Styles and the Design of Network-based Software Architectures」で最初に記述しました。これは少し難しい読み物かもしれませんが、Martin FowlerのRichardson Maturity Modelは、より分かりやすい入門書となるでしょう。

RESTは、ほとんどのソフトウェアアーキテクチャよりも多くの方法で解釈され、誤解されてきました。Roy Fieldingの原則をアーキテクチャで多く採用するほど、アプリケーションは「RESTful」と見なされるでしょう。

CodeIgniterは、リソースルートと`ResourceController`を使用して、リソースのRESTful APIを簡単に作成できます。

リソースルート

`resource()`メソッドを使用して、単一のリソースに対していくつかのRESTfulルートを迅速に作成できます。これにより、リソースの完全なCRUDに必要な5つの最も一般的なルート(新規リソースの作成、既存リソースの更新、すべてのリソースの一覧表示、単一のリソースの表示、単一リソースの削除)が作成されます。最初の引数はリソース名です。

<?php

$routes->resource('photos');

// Equivalent to the following:
$routes->get('photos/new', 'Photos::new');
$routes->post('photos', 'Photos::create');
$routes->get('photos', 'Photos::index');
$routes->get('photos/(:segment)', 'Photos::show/$1');
$routes->get('photos/(:segment)/edit', 'Photos::edit/$1');
$routes->put('photos/(:segment)', 'Photos::update/$1');
$routes->patch('photos/(:segment)', 'Photos::update/$1');
$routes->delete('photos/(:segment)', 'Photos::delete/$1');

注記

上記の順序は明確にするためのものであり、RouteCollectionでルートが実際に作成される順序は、適切なルート解決を保証します。

重要

ルートは指定された順序で照合されるため、リソース`photos`の上に`GET 'photos/poll'`がある場合、リソース行のshowアクションのルートは`GET`行よりも先に照合されます。これを修正するには、`GET`行をリソース行の上に移動して、先に照合されるようにします。

2番目の引数には、生成されるルートを変更するために使用できるオプションの配列を受け入れます。これらのルートはより多くのメソッドが許可されるAPIの使用を目的としていますが、`websafe`オプションを渡して、HTMLフォームで動作する更新および削除メソッドを生成させることができます。

<?php

$routes->resource('photos', ['websafe' => 1]);

// The following equivalent routes are created:
$routes->post('photos/(:segment)/delete', 'Photos::delete/$1');
$routes->post('photos/(:segment)', 'Photos::update/$1');

使用するコントローラーの変更

`controller`オプションに使用するコントローラーの名前を渡すことで、使用するコントローラーを指定できます。

<?php

$routes->resource('photos', ['controller' => 'Gallery']);
// Would create routes like:
$routes->get('photos', '\App\Controllers\Gallery::index');
<?php

$routes->resource('photos', ['controller' => '\App\Gallery']);
// Would create routes like:
$routes->get('photos', '\App\Gallery::index');
<?php

use App\Controllers\Gallery;

$routes->resource('photos', ['namespace' => '', 'controller' => Gallery::class]);
// Would create routes like:
$routes->get('photos', '\App\Controllers\Gallery::index');

参照: コントローラーの名前空間.

使用するプレースホルダーの変更

デフォルトでは、リソースIDが必要な場合に`(:segment)`プレースホルダーが使用されます。`placeholder`オプションに新しい文字列を渡すことで、これを変更できます。

<?php

$routes->resource('photos', ['placeholder' => '(:num)']);

// Generates routes like:
$routes->get('photos/(:num)', 'Photos::show/$1');

作成されるルートの制限

`only`オプションを使用して、生成されるルートを制限できます。これは、作成するメソッド名の**配列**または**カンマ区切りのリスト**である必要があります。これらのメソッドのいずれかに一致するルートのみが作成されます。残りは無視されます。

<?php

$routes->resource('photos', ['only' => ['index', 'show']]);

または、`except`オプションを使用して使用されていないルートを削除できます。これも**配列**または**カンマ区切りのリスト**である必要があります。このオプションは`only`の後で実行されます。

<?php

$routes->resource('photos', ['except' => 'new,edit']);

有効なメソッドは`index`、`show`、`create`、`update`、`new`、`edit`、`delete`です。

ResourceController

`ResourceController`は、上記のResourceルートに対応するメソッドを備えた、RESTful APIの便利な出発点です。

`modelName`と`format`プロパティをオーバーライドして拡張し、処理するメソッドを実装します。

<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourceController;

class Photos extends ResourceController
{
    protected $modelName = 'App\Models\Photos';
    protected $format    = 'json';

    public function index()
    {
        return $this->respond($this->model->findAll());
    }

    // ...
}

これのルーティングは次のようになります。

<?php

$routes->resource('photos');

プレゼンタールート

`presenter()`メソッドを使用して、リソースコントローラーと連携するプレゼンテーションコントローラーを迅速に作成できます。これにより、リソースのビューを返すか、それらのビューから送信されたフォームを処理するコントローラーメソッドのルートが作成されます。

これは、従来のコントローラーでプレゼンテーションを処理できるため、必須ではありません。これは便宜的なものです。その使用方法はリソースルーティングに似ています。

<?php

$routes->presenter('photos');

// Equivalent to the following:
$routes->get('photos/new', 'Photos::new');
$routes->post('photos/create', 'Photos::create');
$routes->post('photos', 'Photos::create');   // alias
$routes->get('photos', 'Photos::index');
$routes->get('photos/show/(:segment)', 'Photos::show/$1');
$routes->get('photos/(:segment)', 'Photos::show/$1');  // alias
$routes->get('photos/edit/(:segment)', 'Photos::edit/$1');
$routes->post('photos/update/(:segment)', 'Photos::update/$1');
$routes->get('photos/remove/(:segment)', 'Photos::remove/$1');
$routes->post('photos/delete/(:segment)', 'Photos::delete/$1');

注記

上記の順序は明確にするためのものであり、RouteCollectionでルートが実際に作成される順序は、適切なルート解決を保証します。

リソースコントローラーとプレゼンターコントローラーの両方について`photos`のルートを持つことはできません。例えば、それらを区別する必要があります。

<?php

$routes->resource('api/photo');
$routes->presenter('admin/photos');

2番目の引数には、生成されるルートを変更するために使用できるオプションの配列を受け入れます。

使用するコントローラーの変更

`controller`オプションに使用するコントローラーの名前を渡すことで、使用するコントローラーを指定できます。

<?php

$routes->presenter('photos', ['controller' => 'Gallery']);
// Would create routes like:
$routes->get('photos', '\App\Controllers\Gallery::index');
<?php

$routes->presenter('photos', ['controller' => '\App\Gallery']);
// Would create routes like:
$routes->get('photos', '\App\Gallery::index');
<?php

use App\Controllers\Gallery;

$routes->presenter('photos', ['namespace' => '', 'controller' => Gallery::class]);
// Would create routes like:
$routes->get('photos', '\App\Controllers\Gallery::index');

参照: コントローラーの名前空間.

使用するプレースホルダーの変更

デフォルトでは、リソースIDが必要な場合に`(:segment)`プレースホルダーが使用されます。`placeholder`オプションに新しい文字列を渡すことで、これを変更できます。

<?php

$routes->presenter('photos', ['placeholder' => '(:num)']);

// Generates routes like:
$routes->get('photos/(:num)', 'Photos::show/$1');

作成されるルートの制限

`only`オプションを使用して、生成されるルートを制限できます。これは、作成するメソッド名の**配列**または**カンマ区切りのリスト**である必要があります。これらのメソッドのいずれかに一致するルートのみが作成されます。残りは無視されます。

<?php

$routes->presenter('photos', ['only' => ['index', 'show']]);

または、`except`オプションを使用して使用されていないルートを削除できます。これも**配列**または**カンマ区切りのリスト**である必要があります。このオプションは`only`の後で実行されます。

<?php

$routes->presenter('photos', ['except' => 'new,edit']);

有効なメソッドは`index`、`show`、`new`、`create`、`edit`、`update`、`remove`、`delete`です。

ResourcePresenter

`ResourcePresenter`は、上記のResourceルートと連携するメソッドを使用して、リソースのビューを提示し、それらのビューのフォームからデータの処理を行うための便利な出発点を提供します。

`modelName`プロパティをオーバーライドして拡張し、処理するメソッドを実装します。

<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourcePresenter;

class Photos extends ResourcePresenter
{
    protected $modelName = 'App\Models\Photos';

    public function index()
    {
        return view('templates/list', $this->model->findAll());
    }

    // ...
}

これのルーティングは次のようになります。

<?php

$routes->presenter('photos');

プレゼンター/コントローラーの比較

この表は、`resource()`と`presenter()`によって作成されたデフォルトのルートとその対応するコントローラー関数の比較を示しています。

操作

メソッド

コントローラールート

プレゼンタールート

コントローラー関数

プレゼンター関数

新規

GET

photos/new

photos/new

new()

new()

作成

POST

photos

photos

create()

create()

作成(エイリアス)

POST

photos/create

create()

一覧

GET

photos

photos

index()

index()

表示

GET

photos/(:segment)

photos/(:segment)

show($id = null)

show($id = null)

表示(エイリアス)

GET

photos/show/(:segment)

show($id = null)

編集

GET

photos/(:segment)/edit

photos/edit/(:segment)

edit($id = null)

edit($id = null)

更新

PUT/PATCH

photos/(:segment)

update($id = null)

更新(websafe)

POST

photos/(:segment)

photos/update/(:segment)

update($id = null)

update($id = null)

削除

GET

photos/remove/(:segment)

remove($id = null)

削除

DELETE

photos/(:segment)

delete($id = null)

削除(websafe)

POST

photos/delete/(:segment)

delete($id = null)

delete($id = null)