CodeIgniter4 處理RESTful請(qǐng)求資源

2020-08-17 15:23 更新

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

對(duì)于REST的架構(gòu)方式,比起大多數(shù)軟件架構(gòu)體系,大家理解和誤解得會(huì)更多。 或者可以這樣說,當(dāng)你將Roy Fielding的原則越多得使用在一個(gè)架構(gòu)中,你的應(yīng)用就會(huì)變得越”RESTful”。

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

資源路由

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

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

注解

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

重要

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

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

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


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

更改所使用的控制器

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

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


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

更改使用的通配符

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

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


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

限制生成的路由

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

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

反過來你也可以通過 except 選項(xiàng)來移除那些不使用的路由。該選項(xiàng)就在 only 后運(yùn)行:

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

合理的請(qǐng)求類型為: index, show, create, update, new, edit and delete.

資源控制器

ResourceController 為開始你的RESTful API的構(gòu)建提供了一個(gè)非常便利的起點(diǎn),實(shí)現(xiàn)了上述列舉的資源路由的請(qǐng)求類型。

繼承或重載 modelName 和 format 屬性,并實(shí)現(xiàn)你想要處理的請(qǐng)求類型:

<?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());
        }


        // ...
}

上述路由結(jié)構(gòu)如下:

$routes->resource('photos');

表現(xiàn)層路由

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

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

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

注解

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

可能對(duì)于 photos 你可能并不準(zhǔn)備同時(shí)構(gòu)建資源和表現(xiàn)層控制器,因此你需要對(duì)它們進(jìn)行區(qū)分,例如:

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

第二個(gè)參數(shù)接受一個(gè)選項(xiàng)數(shù)組,用于修改生成的路由

更改所使用的控制器

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

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


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

更改所使用的通配符

默認(rèn)情況下,當(dāng)需要資源ID時(shí),我們使用 segment 通配符。你可以通過為 placeholder 選項(xiàng)傳值一個(gè)新的字符串來指定新的通配符:

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


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

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

你可以通過 only 選項(xiàng)來限制生成的路由。該選項(xiàng)的傳值應(yīng)當(dāng)是一個(gè)數(shù)組或者是一個(gè)逗號(hào)分隔的,由所需要?jiǎng)?chuàng)建的方法的名字構(gòu)成的列表。只有匹配上述方法的路由會(huì)被創(chuàng)建而其余的會(huì)被忽略:

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

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

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

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

ResourcePresenter(資源表現(xiàn)器) ResourcePresenter ============================================================

ResourcePresenter 為你輸出一個(gè)資源對(duì)應(yīng)的視圖提供了一個(gè)便捷的起點(diǎn),而它同樣也可利用屬于該資源路由的方法來處理這些視圖里提交的表單。

繼承或重載 modelName 屬性,并實(shí)現(xiàn)那些你所需要調(diào)用的方法:

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

表現(xiàn)器/控制器對(duì)比

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

操作 方法 控制器路由 表現(xiàn)層路由 控制器方法 表現(xiàn)層方法
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)
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)