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 资源所需的:创建新资源、更新现有资源、列出所有该资源、显示单个资源以及删除单个资源。第一个参数是资源名称

<?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 中创建的实际顺序确保了正确的路由解析

重要

路由按指定顺序匹配,因此如果您在 get 'photos/poll' 之上有一个资源照片,则资源行的 show 操作的路由将在 get 行之前匹配。要解决此问题,请将 get 行移到资源行之上,以便它首先匹配。

第二个参数接受一个选项数组,可用于修改生成的路由。虽然这些路由针对 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']);

有效方法包括:indexshowcreateupdateneweditdelete

ResourceController

ResourceController 为您的 RESTful API 提供了一个方便的起点,其中包含与上述资源路由相对应的方法。

扩展它,覆盖 modelNameformat 属性,然后实现您想要处理的那些方法。

<?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');

第二个参数接受一个选项数组,可用于修改生成的路由。

更改使用的控制器

您可以通过传递 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']);

有效方法为:indexshownewcreateeditupdateremovedelete

ResourcePresenter

ResourcePresenter 为呈现资源视图并处理这些视图中表单的数据提供了一个方便的起点,其方法与上面的资源路由一致。

扩展它,覆盖 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)

更新(网络安全)

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)

删除(网络安全)

POST

photos/delete/(:segment)

delete($id = null)

delete($id = null)