RestUserController
controller with methods:actionIndex
- list of usersactionView
- view useractionCreate
- create useractionUpdate
- update useractionDelete
- delete userRestUser
model, which is the ActvieRecord of the rest_users table.actionCreate
method, whose task is to create a new RestUser
user, class RestUserController extends Controller { ... public function actionCreate() { $model = new RestUser(); if (isset($_POST) && ($data = $_POST)) { // POST $model->attributes = $data; // if ($model->save()) { // , - $this->redirect(array('view', 'id' => $model->id)); } } $this->render('create', array('model' => $model)); // html- } ... }
/restUser/create
- the html-form for adding a new user is displayed, if we send a POST request to this address, then the validation and addition logic works, then either redirects us to the user’s view, or displays the html-form c errors. curl http://test.local/api/users \ -u demo:demo \ -d email="user@test.local" \ -d password="passwd"
< HTTP/1.1 201 Created < Content-Type: application/json < WWW-Authenticate: Basic realm="App" < Location: http://test.local/api/users/TEST_ID { "object":"rest_user", "id":"TEST_ID", "email":"user@test.local", "name":"Test REST User" }
redirect
and render
methods, and also by adding rules for rendering models.onException
and onError
, as well as adding additional functionality to the CActiveRecord
base model and the onError
CController
using behaviors . class RestUserController extends Controller { ... public function actionCreate() { $model = new RestUser(); if ($this->isPost() && ($data = $_POST)) { // isPost isPut isDelete $model->attributes = $data; if ($model->save()) { $this->redirect(array('view', 'id' => $model), true, 201); // } } $this->render('create', array('model' => $model), false, array('model')); // model } ... }
redirect
method as an id
parameter, not $model->id
, but the $model
object, in order for the created object to be returned to the client. Also, the third parameter was added response code 201 - this is necessary to meet the standard, because along with the response, the Location header is sent, containing the address of the created object. 3xx HTTP codes are not allowed in the response.render
method, it contains an enumeration of fields from the $data
array passed to the client in response. If the parameter is null
then the entire $data
array is returned. curl http://test.local/api/users \ -u demo:demo \ -d email="user@test.local"
< HTTP/1.1 400 Bad Request < Content-Type: application/json < WWW-Authenticate: Basic realm="App" { "error":{ "params":[ { "code":"required", "message":"Password cannot be blank.", "name":"password" } ], "type":"invalid_param_error", "message":"Invalid data parameters" } }
RestUser
a password
field. To do this, we define in the rule list of returned fields.rules
method class RestUser extends CModel { public function rules() { return array( ... array('id, email, name', 'safe', 'on' => 'render'), ); } }
getRenderAttributes
method added to the model, which will return all the attributes available for display by an array, recursively traversing the object's connections if they are specified in the rule.\rest\Service
component (service), which deals with basic event handling and the correct display of data. This service has two groups of auth
and renderer
adapters.auth
has authentication adapters - the default basic auth HTTP adapter is available.renderer
contains adapters that perform data mapping — by default, two JSON and XML adapters are available.main.php
YiiBase::setPathOfAlias('rest', realpath(__DIR__ . '/../extensions/yii-rest-api/library/rest')); return array( 'basePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR . '..', 'name' => 'My Web Application', 'preload' => array('restService'), 'import' => array( 'application.models.*', 'application.components.*', ), 'components' => array( 'restService' => array( 'class' => '\rest\Service', 'enable' =>strpos($_SERVER['REQUEST_URI'], '/api/') !== false, // ), 'urlManager' => array( 'urlFormat' => 'path', 'showScriptName' => false, 'baseUrl' => '', 'rules' => array( array('restUser/index', 'pattern' => 'api/v1/users', 'verb' => 'GET', 'parsingOnly' => true), array('restUser/create', 'pattern' => 'api/v1/users', 'verb' => 'POST', 'parsingOnly' => true), array('restUser/view', 'pattern' => 'api/v1/users/<id>', 'verb' => 'GET', 'parsingOnly' => true), array('restUser/update', 'pattern' => 'api/v1/users/<id>', 'verb' => 'PUT', 'parsingOnly' => true), array('restUser/delete', 'pattern' => 'api/v1/users/<id>', 'verb' => 'DELETE', 'parsingOnly' => true), array('restUser/index2', 'pattern' => 'api/v2/users', 'verb' => 'GET', 'parsingOnly' => true), // , API ) ), ), );
/** * @method bool isPost() * @method bool isPut() * @method bool isDelete() * @method string renderRest(string $view, array $data = null, bool $return = false, array $fields = array()) * @method void redirectRest(string $url, bool $terminate = true, int $statusCode = 302) * @method bool isRestService() * @method \rest\Service getRestService() */ class RestUserController extends Controller { public function behaviors() { return array( 'restAPI' => array('class' => '\rest\controller\Behavior') ); } // $fields , public function render($view, $data = null, $return = false, array $fields = array('count', 'model', 'data')) { if (($behavior = $this->asa('restAPI')) && $behavior->getEnabled()) { if (isset($data['model']) && $this->isRestService() && count(array_intersect(array_keys($data), $fields)) == 1) { $data = $data['model']; // API, , - $fields = null; } return $this->renderRest($view, $data, $return, $fields); } else { return parent::render($view, $data, $return); } } public function redirect($url, $terminate = true, $statusCode = 302) { if (($behavior = $this->asa('restAPI')) && $behavior->getEnabled()) { $this->redirectRest($url, $terminate, $statusCode); } else { parent::redirect($url, $terminate, $statusCode); } } }
/** * @method array getRenderAttributes(bool $recursive = true) * @method string getObjectId() */ class RestUser extends CActiveRecord { /** * @return array */ public function behaviors() { return array( 'renderModel' => array('class' => '\rest\model\Behavior') ); } }
Source: https://habr.com/ru/post/155021/
All Articles