我正在尝试使用YII2 REST API(基于高级模板)来创建自己的服务。我目前正在使用以下URL成功返回一条“文章”记录:
http://service/articles/view?id=1
我现在正在尝试复制此代码,因此它适用于其他记录类型。我的新记录有一个名为' key '的主键,我想搜索一下。因此,我需要将参数名称“ id ”更改为“ key ”。
有人可以解释如何在此网址上指定“ id ”以外的参数吗?每当我省略id作为参数时,我得到一个“错误请求:缺少必需参数:id ”。我不明白这个必需参数的来源以及如何更改或添加它。
相关课程如下:
class ArticleController extends ActiveController
{
/**
* @var string
*/
public $modelClass = 'frontend\modules\api\v1\resources\Article';
/**
* @var array
*/
public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items'
];
/**
* @inheritdoc
*/
public function actions()
{
return [
'index' => [
'class' => 'yii\rest\IndexAction',
'modelClass' => $this->modelClass,
'prepareDataProvider' => [$this, 'prepareDataProvider']
],
'view' => [
'class' => 'yii\rest\ViewAction',
'modelClass' => $this->modelClass,
'findModel' => [$this, 'findModel']
],
'options' => [
'class' => 'yii\rest\OptionsAction'
]
];
}
/**
* @return ActiveDataProvider
*/
public function prepareDataProvider()
{
return new ActiveDataProvider(array(
'query' => Article::find()->published()
));
}
/**
* @param $id
* @return array|null|\yii\db\ActiveRecord
* @throws HttpException
*/
public function findModel($id)
{
$model = Article::find()
->published()
->andWhere(['id' => (int) $id])
->one();
if (!$model) {
throw new HttpException(404);
}
return $model;
}
}
class Article extends \common\models\Article implements Linkable
{
public function fields()
{
return ['id', 'slug', 'category_id', 'title', 'body', 'published_at'];
}
public function extraFields()
{
return ['category'];
}
/**
* Returns a list of links.
*
* @return array the links
*/
public function getLinks()
{
return [
Link::REL_SELF => Url::to(['article/view', 'id' => $this->id], true)
];
}
}
提前致谢。
编辑:'frontend'文件夹结构中urlManager的规范如下:
<?php
return [
'class'=>'yii\web\UrlManager',
'enablePrettyUrl'=>true,
'showScriptName'=>false,
'rules'=> [
// Pages
['pattern'=>'page/<slug>', 'route'=>'page/view'],
// Articles
['pattern'=>'article/index', 'route'=>'article/index'],
['pattern'=>'article/attachment-download', 'route'=>'article/attachment-download'],
['pattern'=>'article/<slug>', 'route'=>'article/view'],
// Api
['class' => 'yii\rest\UrlRule', 'controller' => 'api/v1/article', 'only' => ['index', 'view', 'options']],
['class' => 'yii\rest\UrlRule', 'controller' => 'api/v1/user', 'only' => ['index', 'view', 'options']]
]
];
答案 0 :(得分:1)
我不知道这是否是官方的做法,但我已经创建了一个额外的Action来处理这种情况。似乎“id”参数来自于反映Action中的“run”方法调用,因此我可以使用一个名为“key”的不同参数的唯一方法是通过完全相同的方式定义函数:
class ExtraAction extends Action // in yii/rest
{
public function run($key) // NOTE: The name 'key' is reflected and then becomes an expected parameter
{
$model = $this->findModel($key);
if (!$model) {
throw new HttpException(404);
}
return $model;
}
}
完成后,我需要更改我的actions()定义,如下所示:
'view' => [
'class' => 'yii\rest\ExtraAction',
'modelClass' => $this->modelClass,
'findModel' => [$this, 'findModel']
],
控制器中的findModel($ id)将接收GET URL中定义的'key'参数(例如,api / v1 / article?key = blah123)。
然后我可以根据我拥有的不同唯一键执行查找:
public function findModel($id)
{
$model = Record::find()
->andWhere(['key_field' => $id])
->one();
}
我不知道这是否是正确的做法,但它确实适用于这种情况。
答案 1 :(得分:1)
这可以通过在配置文档中向urlmanager添加规则来实现here
示例:
'rules' => [
[ 'class' => 'yii\rest\UrlRule',
'pluralize' => false,
'controller' => [
'yourController',
],
'patterns' => [
'PUT,PATCH {id}' => 'update',
'DELETE {id}' => 'delete',
'GET,HEAD {id}' => 'view',
'GET,HEAD {key}' => 'view',
'POST' => 'create',
'GET,HEAD' => 'index',
'{id}' => 'options',
'OPTIONS' => 'options',
'PUT,PATCH {key}' => 'update',
],
'tokens' => [
'{id}' => '<id:\\d[\\d,]*>',
'{type}' => '<type:\\w[\\w,]*>',
'{key}' => '<key:\\w[\\w,]*>',
],
],
]
将动作映射添加到yourController
class YourController extends ActiveController {
public $modelClass = 'your\model\Class';
public function actions() {
return array_merge(parent::actions(), [
'view' => [
'class' => \rest\your\ViewAction',
'modelClass' => $this->modelClass,
],
]);
}
}
并将密钥参数添加到您的操作
class ViewAction extends \yii\rest\ViewAction {
public function run($id = null, $key = null)
{
// your code
}
}
现在你应该能够做到这一点
GET your/{keyparam} -> wil resolve to yourController -> ViewAction
答案 2 :(得分:0)
像往常一样在public function actionView2($your_desired_parameter) {
$article = Article::find()->where(['your_desired_parameter'=>$your_desired_parameter]);
if (!$article->exists())
throw new NotFoundHttpException();
return $article->one();
}
内创建新方法:
?v