CodeIgniter4 處理RESTful請求資源

2020-08-17 15:23 更新

表現層狀態(tài)轉移(REST)是一種對于分布式應用的架構風格,最初由Roy Fielding在他的2000年博士論文 Architectural Styles and the Design of Network-based Software Architectures 所提出。 上文可能讀起來有些枯燥,你也可以參照Martin Fowler的 Richardson Maturity Model 以獲得更方便的教程。

對于REST的架構方式,比起大多數軟件架構體系,大家理解和誤解得會更多。 或者可以這樣說,當你將Roy Fielding的原則越多得使用在一個架構中,你的應用就會變得越”RESTful”。

CodeIgniter實現了一種簡易的方式來創(chuàng)建RESTful API從而訪問你的資源,通過其自帶的資源路由和 ResourceController (資源控制器)。

資源路由

對單個資源,你可以通過 resource() 方法來創(chuàng)建一個方便的RESTful路由。這種方式可以創(chuàng)建五種對于操作資源的CRUD方式,最為常見的比如: 創(chuàng)建一個資源,更新一個已存在的資源,列出所有這類資源,獲取一個單獨資源以及刪除一個單獨的資源。第一個參數就是這個資源的名字:

$routes->resource('photos');


// 與以下方式等同:
$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中的創(chuàng)建順序已經確保了路由可以被正確地解析。

重要

路由是由它們所定義的順序而進行匹配的,因此如果像上面一樣,如果你有一個GET資源圖片請求,類似 “photos/poll” 一樣,那么show的請求路由會比get請求優(yōu)先被匹配。為了解決這個問題,將get請求這行移到資源行的頂部,從而它可以被首先匹配。

第二個參數接受的是一個包含著用于修改生成路由方式的選項數組。盡管這些路由通過API調用的,且這里支持更多的請求類型,你還是可以通過傳遞“websafe”選項來生成update和delete請求類型來處理HTML表單:

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


// 將會創(chuàng)建以下的同等效應的路由:
$routes->post('photos/(:segment)/delete', 'Photos::delete/$1');
$routes->post('photos/(:segment)',        'Photos::update/$1');

更改所使用的控制器

你可以通過指定所使用的控制器,通過為 controller 選項傳值:

$routes->resource('photos', ['controller' =>'App\Gallery']);


// 將會創(chuàng)建如下路由
$routes->get('photos', 'App\Gallery::index');

更改使用的通配符

默認情況下,在需要資源ID時,我們需要使用 segment 占位符。你可以通過為 placeholder 選項傳值一個新的字符串來實現這一操作:

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


// 將會創(chuàng)建如下路由:
$routes->get('photos/(:id)', 'Photos::show/$1');

限制生成的路由

你可以通過 only 選項來限制所生成的路由。這個選項的傳值可以是一個數組或者是一個由逗號分隔的列表,其中包含著需要創(chuàng)建的類型名。而剩余的將會被忽略:

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

反過來你也可以通過 except 選項來移除那些不使用的路由。該選項就在 only 后運行:

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

合理的請求類型為: index, show, create, update, new, edit and delete.

資源控制器

ResourceController 為開始你的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());
        }


        // ...
}

上述路由結構如下:

$routes->resource('photos');

表現層路由

你可以使用 presenter() 方法來創(chuàng)建一個表現層路由,并分配給對應的資源控制器。 這將會為那些給你的資源返回視圖的的控制器方法創(chuàng)建路由,或者處理從這些控制器所創(chuàng)建的視圖里發(fā)送的表單請求。

由于表現層慣例是由一個通用控制器來處理,這個功能不是必需的。它的用法與一個資源路由類似:

$routes->presenter('photos');


// 與如下等同:
$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::update/$1');

注解

上述的排序方式是為了排版清晰起見,而實際上這些路由在RouteCollection中的創(chuàng)建順序已經確保了路由可以被正確地解析

可能對于 photos 你可能并不準備同時構建資源和表現層控制器,因此你需要對它們進行區(qū)分,例如:

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

第二個參數接受一個選項數組,用于修改生成的路由

更改所使用的控制器

你可以通過為 controller 選項傳遞需要更改的控制器的名字來指定實際用到的控制器:

$routes->presenter('photos', ['controller' =>'App\Gallery']);


// 創(chuàng)建的路由如下:
$routes->get('photos', 'App\Gallery::index');

更改所使用的通配符

默認情況下,當需要資源ID時,我們使用 segment 通配符。你可以通過為 placeholder 選項傳值一個新的字符串來指定新的通配符:

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


// 生成路由如下:
$routes->get('photos/(:id)', 'Photos::show/$1');

限制生成的路由 Limit the Routes Made ———————

你可以通過 only 選項來限制生成的路由。該選項的傳值應當是一個數組或者是一個逗號分隔的,由所需要創(chuàng)建的方法的名字構成的列表。只有匹配上述方法的路由會被創(chuàng)建而其余的會被忽略:

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

反過來你也可以通過 except 選項來去除那些無用的路由,該選項位于 only 之后:

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

可使用的方法為: index, show, new, create, edit, update, remove 和 delete.

ResourcePresenter(資源表現器) 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());
        }


        // ...
}

上述路由如下所示:

$routes->presenter('photos');

表現器/控制器對比

下表對比了用 resource() 和 presenter() 分別創(chuàng)建的默認路由以及對應的控制器方法。

操作 方法 控制器路由 表現層路由 控制器方法 表現層方法
New GET photos/new photos/new new() new()
Create POST photos photos create() create()
Create (alias) POST photos/create create()
List GET photos photos index() index()
Show GET photos/(:segment) photos/(:segment) show($id = null) show($id = null)
Show (alias) GET photos/show/(:segment) show($id = null)
Edit GET photos/(:segment)/edit photos/edit/(:segment) edit($id = null) edit($id = null)
Update PUT/PATCH photos/(:segment) update($id = null)
Update (websafe) POST photos/(:segment) photos/update/(:segment) update($id = null) update($id = null)
Remove GET photos/remove/(:segment) remove($id = null)
Delete DELETE photos/(:segment) delete($id = null)
Delete (websafe) POST photos/delete/(:segment) delete($id = null) delete($id = null)
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號