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