Yii2 框架內建強大的 RESTful API 支援,僅需少量設定即可為現有 Model 提供標準化的 RESTful 介面。本文深入剖析 Yii2 RESTful 模組的原始碼結構,解析其核心運作原理,並示範如何擴充功能以支援關聯模型的完整 CRUD 操作。
Yii2 RESTful 模組採用清晰的繼承層級:
rest\Action 繼承自 \yii\base\Actionrest\Controller 繼承自 \yii\web\Controllerrest\ActiveController 繼承自 rest\ControllerCreateAction、DeleteAction、IndexAction、OptionsAction、UpdateAction、ViewAction)皆繼承自 rest\ActionSerializer 繼承自 yii\base\ComponentUrlRule 繼承自 yii\web\CompositeUrlRuleController 是所有 RESTful API 控制器的基類,在請求處理週期中依序執行五大核心步驟:
ContentNegotiator 解析回應格式(JSON/XML)VerbFilter 驗證 HTTP 方法CompositeAuth 整合多種認證方式RateLimiter 實作 API 限流Serializer 格式化回應資料class Controller extends \yii\web\Controller {
public $serializer = 'yii\rest\Serializer';
public $enableCsrfValidation = false;
public function behaviors() {
return [
'contentNegotiator' => [
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
],
],
'verbFilter' => [
'class' => VerbFilter::className(),
'actions' => $this->verbs(),
],
'authenticator' => [
'class' => CompositeAuth::className(),
],
'rateLimiter' => [
'class' => RateLimiter::className(),
],
];
}
public function verbs() { return []; }
public function serializeData($data) {
return Yii::createObject($this->serializer)->serialize($data);
}
public function afterAction($action, $result) {
$result = parent::afterAction($action, $result);
return $this->serializeData($result);
}
}
ActiveController 提供與 ActiveRecord 互動的標準 RESTful 方法,預設支援:
index:模型列表view:單一模型詳情create:建立新模型update:更新現有模型delete:刪除模型options:允許的 HTTP 方法可透過覆寫 actions() 移除或新增動作,並需同步調整 verbs() 與 checkAccess() 以確保權限控管。
namespace app\controllers;
use app\controllers\rest\ActiveController;
class NewsController extends ActiveController {
public $modelClass = 'app\models\News';
// 自訂序列化器
public $serializer = [
'class' => 'app\controllers\rest\Serializer',
'collectionEnvelope' => 'items',
];
public function behaviors() {
return ArrayHelper::merge(parent::behaviors(), [
'verbFilter' => [
'class' => VerbFilter::className(),
'actions' => [
'index' => ['get'],
// 其他動作對應的 HTTP 方法
],
],
'authenticator' => [
'class' => CompositeAuth::className(),
'authMethods' => [
HttpBasicAuth::className(),
HttpBearerAuth::className(),
QueryParamAuth::className(),
],
],
'contentNegotiator' => [
'class' => ContentNegotiator::className(),
'formats' => [
'text/html' => Response::FORMAT_HTML,
],
],
'access' => [
'class' => AccessControl::className(),
'only' => ['view'],
'rules' => [
['actions' => ['view'], 'allow' => false, 'roles' => ['@']],
],
],
]);
}
public function checkAccess($action, $model = null, $params = []) {
// 實作權限檢查邏輯
}
}
當需對關聯模型進行大幅度 CRUD 操作時,建議複製原始 Action 類別進行修改,避免直接修改框架核心。以 UpdateAction 為例,預設僅處理主模型,經改造後可同步更新關聯模型:
public function run($id) {
$model = $this->findModel($id);
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id, $model);
}
$model->scenario = $this->scenario;
// 處理 x-www-form-urlencoded 格式的關聯資料
$newsItem = Yii::$app->getRequest()->getBodyParams()['newsItem'];
$model->newsItem->load($newsItem, '');
if ($model->save()) {
$model->load(Yii::$app->getRequest()->getBodyParams(), '');
$model->newsItem->save();
}
return $model;
}
注意:生產環境需加入關聯模型儲存失敗的錯誤處理與交易控制。
Yii2 RESTful API 架構設計優雅,透過行為與動作類別的組合,提供高度可擴充的 API 開發體驗。掌握核心類別職責與繼承關係,能靈活應對各種業務場景,包含關聯資料處理、權限控管、格式協商等進階需求。