{"id":324913,"date":"2021-06-15T09:00:17","date_gmt":"2021-06-15T09:00:17","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=324913"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=324913","title":{"rendered":"\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e \u043a\u043e\u0434\u0443 \u0434\u043b\u044f API \u0432 Laravel"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u041d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u0434\u044d\u0439\u043b\u0438\u043a\u043e\u0432, \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043f\u043e\u0434\u043d\u044f\u043b\u0438 \u0432\u043e\u043f\u0440\u043e\u0441 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e API \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041f\u043e \u0433\u043e\u0440\u044f\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0430\u043c \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u0448\u043b\u0438, \u0447\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u0442\u044b\u043a\u043e\u0432\u043a\u0438: \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u043e\u0444\u0438\u043a\u0441\u0438\u043b \u0431\u0430\u0433, \u043d\u043e \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043b \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u043f\u043e \u0440\u043e\u0443\u0442\u0443. \u0422\u0430\u043a \u043a\u0430\u043a \u0442\u0430\u043a\u043e\u0435 \u0443\u0436\u0435 \u0441\u043b\u0443\u0447\u0430\u043b\u043e\u0441\u044c \u043d\u0435 \u0432\u043f\u0435\u0440\u0432\u044b\u0435 &#8212; \u0431\u044b\u043b\u0430 \u0437\u0430\u0432\u0435\u0434\u0435\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0430 \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441 \u044d\u0442\u0438\u043c \u043f\u043e\u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<p>\u0416\u0434\u0430\u0442\u044c \u0434\u043e\u043b\u0433\u043e \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c, \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 <strong>PHP<\/strong> c <strong>7.2<\/strong> \u0434\u043e <strong>7.4<\/strong> &#8212; \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0438, \u0432\u043c\u0435\u0441\u0442\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u041e\u0448\u0438\u0431\u043a\u0430 \u0431\u044b\u043b\u0430 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0431\u044b\u0441\u0442\u0440\u043e &#8212; \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 <strong>UI<\/strong> \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u041f\u0420 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u0431\u044b\u0441\u0442\u0440\u043e, \u043d\u043e \u043f\u0440\u043e\u0432\u0438\u0441\u0435\u043b \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 open \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0434\u0435\u043b\u044e. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e, \u0442\u0438\u043a\u0435\u0442 \u043d\u0430\u0441\u0447\u0435\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438  \u043f\u043e\u0448\u0435\u043b \u0432 \u0440\u0430\u0431\u043e\u0442\u0443.<\/p>\n<h2>\u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u0435\u043b<\/h2>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435:<\/p>\n<ul>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 &#8212; Laravel 7<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f &#8212; Blueprint Docs<em> <\/em><a href=\"https:\/\/github.com\/M165437\/laravel-blueprint-docs\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/M165437\/laravel-blueprint-docs<\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u043d\u0435 \u0432 \u043a\u0443\u0440\u0441\u0435 \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u0442\u043e \u0441\u043c\u044b\u0441\u043b \u0442\u0430\u043a\u043e\u0439: \u0435\u0441\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b (<strong>*.apib<\/strong>), \u0441\u043e \u0441\u0432\u043e\u0438\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u043e\u043c, \u0438 \u043f\u0430\u0440\u0441\u0435\u0440 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 &#8212; <a href=\"https:\/\/github.com\/apiaryio\/drafter\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/apiaryio\/drafter<\/a>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0447\u0438\u0442\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b. \u041f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b\u043b \u0432\u044b\u0431\u0440\u0430\u043d \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u044f \u043d\u0435 \u0437\u043d\u0430\u044e (\u0431\u044b\u043b\u043e \u0434\u043e \u043c\u0435\u043d\u044f).<\/p>\n<p>\u0418\u0437 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0433\u0443\u0433\u043b, \u0431\u044b\u043b\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0432\u0430 \u043f\u0440\u0435\u0442\u0435\u043d\u0434\u0435\u043d\u0442\u0430:<\/p>\n<ul>\n<li>\n<p>OpenAPI\/Swagger<\/p>\n<\/li>\n<li>\n<p>Laravel API Documentation Generator &#8212; <a href=\"https:\/\/github.com\/mpociot\/laravel-apidoc-generator\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/mpociot\/laravel-apidoc-generator<\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u043e\u0442\u043f\u0430\u043b \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e (\u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e) \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043e\u043a\u0431\u043b\u043e\u043a\u043e\u0432, \u0438 \u044d\u0442\u043e \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0437\u0430\u0431\u044b\u0432\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435. \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f &#8212; <a href=\"https:\/\/blog.quickadminpanel.com\/laravel-api-documentation-with-openapiswagger\/\" rel=\"noopener noreferrer nofollow\">https:\/\/blog.quickadminpanel.com\/laravel-api-documentation-with-openapiswagger\/<\/a><\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0431\u044b\u043b \u043d\u0435\u043f\u043b\u043e\u0445, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0442\u0435\u043c \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u043b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0441\u043f\u043e\u043d\u0437 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430:<\/p>\n<pre><code class=\"php\">\/**  * @apiResourceCollection  Mpociot\\ApiDoc\\Tests\\Fixtures\\UserResource  * @apiResourceModel  Mpociot\\ApiDoc\\Tests\\Fixtures\\User  *\/ public function listUsers() {     return UserResource::collection(User::all()); }  \/**  * @apiResourceCollection  Mpociot\\ApiDoc\\Tests\\Fixtures\\UserResource  * @apiResourceModel  Mpociot\\ApiDoc\\Tests\\Fixtures\\User  *\/ public function showUser(User $user) {     return new UserResource($user); }<\/code><\/pre>\n<p>\u041d\u043e \u0447\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f <strong>Request<\/strong> &#8212; \u0431\u0443\u0434\u044c \u0434\u043e\u0431\u0440 \u0440\u0430\u0441\u043f\u0438\u0448\u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0447\u0442\u043e \u043a \u0447\u0435\u043c\u0443:<\/p>\n<pre><code class=\"php\">\/**  * @urlParam  id required The ID of the post.  * @urlParam  lang The language.  * @bodyParam  user_id int required The id of the user. Example: 9  * @bodyParam  room_id string The id of the room.  * @bodyParam  forever boolean Whether to ban the user forever. Example: false  * @bodyParam  another_one number Just need something here.  * @bodyParam  yet_another_param object required Some object params.  * @bodyParam  yet_another_param.name string required Subkey in the object param.  * @bodyParam  even_more_param array Some array params.  * @bodyParam  even_more_param.* float Subkey in the array param.  * @bodyParam  book.name string  * @bodyParam  book.author_id integer  * @bodyParam  book[pages_count] integer  * @bodyParam  ids.* integer  * @bodyParam  users.*.first_name string The first name of the user. Example: John  * @bodyParam  users.*.last_name string The last name of the user. Example: Doe  *\/ public function createPost() {     \/\/ ... }  \/**  * @queryParam  sort Field to sort by  * @queryParam  page The page number to return  * @queryParam  fields required The fields to include  *\/ public function listPosts() {     \/\/ ... }<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0443 <strong>Request&#8217;a <\/strong>(\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <em>Illuminate\\Foundation\\Http\\FormRequest<\/em>), \u0431\u044b\u043b\u043e \u0431\u044b \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u0418 \u0442\u0443\u0442 \u043f\u0440\u0438\u0448\u043b\u0430 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u043c\u044b\u0441\u043b\u044c: &#171;\u0410 \u043d\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434 \u043d\u0430 PHP&#8230;&#187;.<\/p>\n<p>\u0422\u0430\u043a, \u043a\u0430\u043a \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f (2 BE \u0438 2 FE), \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u043b\u044e\u0448\u043a\u0430\u043c\u0438 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043e\u0447\u043d\u044b\u0445 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u043a\u043e\u0434\u044b \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0438 \u0442\u0434). \u0418\u0434\u0435\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c. \u041f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0440\u043e\u0443\u0442\u043e\u0432 \u0438\u043c\u0435\u044e\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434: <\/p>\n<pre><code class=\"php\">&lt;?php ...     public function bulkApply(BulkApplyRequest $request, BulkApplyHandler $handler)     {         $applies = $handler(BulkApplyData::fromRequest($request), $request-&gt;user());          return $this-&gt;respondWithResource(Apply::collection($applies));     }       public function accept(StatusRequest $request, AcceptHandler $handler)     {         $apply = $handler($request-&gt;get('job_app_id'));          return $this-&gt;respondWithResource(new Apply($apply));     }<\/code><\/pre>\n<p><strong>StatusRequest<\/strong> \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"php\">&lt;?php  use Illuminate\\Foundation\\Http\\FormRequest;  class StatusRequest extends FormRequest {     public function rules()     {         return [             'app_id' =&gt; 'required|exists:apps,id',         ];     } }<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0441\u0445\u0435\u043c\u0430:<\/p>\n<ul>\n<li>\n<p>\u0411\u0435\u0440\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0440\u043e\u0443\u0442\u043e\u0432 \u0438 \u043e\u0442\u0441\u0435\u043a\u0430\u043c \u0432\u0441\u0435 \u0447\u0442\u043e \u043d\u0435 <strong>\/api\/*<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 \u0440\u043e\u0443\u0442\u0430 \u0443\u0437\u043d\u0430\u0435\u043c  <strong>Controller<\/strong> \u0438 <strong>Action<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Reflection API \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u0435\u0442\u043e\u0434\u0430 (\u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 <strong>FormRequest<\/strong>)<\/p>\n<\/li>\n<li>\n<p>\u0412 DocBlock \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0434\u043b\u044f \u043e\u0442\u0432\u0435\u0442\u0430 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <strong>JsonResource<\/strong>)<\/p>\n<\/li>\n<\/ul>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u043e\u0433\u043e<\/h2>\n<p>\u0421 \u0440\u043e\u0443\u0442\u0430\u043c\u0438 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"php\">&lt;?php  declare(strict_types=1);  namespace App\\Services;  use Illuminate\\Routing\\Route; use Illuminate\\Routing\\Router;  class RouterService {     \/** @var Router *\/     private $router;       public function __construct(Router $router)     {         $this-&gt;router = $router;     }       public function getApiRoutes(): array     {         $routes = [];         foreach ($this-&gt;router-&gt;getRoutes()-&gt;getRoutes() as $route) {             if (strpos($route-&gt;uri(), 'api\/') === 0) {                 $routes[] = $route;             }         }          usort($routes, function (Route $a, Route $b) {             return strnatcmp($a-&gt;uri(), $b-&gt;uri());         });          return $routes;     } <\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u0440\u043e\u0443\u0442\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ul>\n<li>\n<p>Auth<\/p>\n<ul>\n<li>\n<p>\/api\/auth\/login<\/p>\n<\/li>\n<li>\n<p>\/api\/auth\/logout<\/p>\n<\/li>\n<li>\n<p>\/api\/auth\/register<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u0412\u043e\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435:<\/p>\n<pre><code class=\"php\">&lt;?php      public function parseRoutes(array $routes): array     {         $rows = [];         foreach ($routes as $group =&gt; $items) {             $rows[$group] = [];             foreach ($items as $route) {                 $tmp = [                     'uri' =&gt; $route-&gt;uri(),                     'methods' =&gt; $route-&gt;methods(),                     'isGuest' =&gt; in_array('guest', $route-&gt;middleware()),                 ];                  $reflection = new ReflectionClass($route-&gt;getController());                  $methodName = Str::parseCallback($route-&gt;getAction('uses'))[1];                 $reflectionMethod = $reflection-&gt;getMethod($methodName);                  $requestParam = $this-&gt;getRequestParam($reflectionMethod);                 $tmp['requestRules'] = $this-&gt;wrapRequestRules($requestParam-&gt;rules());                  $response = $this-&gt;getResponse($reflectionMethod);                 $tmp['response'] = $this-&gt;wrapResponse($response);                  $rows[$group][] = $tmp;             }         }          return $rows;     }<\/code><\/pre>\n<p><strong>isGuest<\/strong> \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0444\u043b\u0430\u0433\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u041d\u0430 17 \u0441\u0442\u0440\u043e\u043a\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. 20 &#8212; 21 \u0441\u0442\u0440\u043e\u043a\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. 23 &#8212; 24 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0440\u0435\u0441\u043f\u043e\u043d\u0437\u043e\u043c.<\/p>\n<p>\u041f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 <strong>FormRequest<\/strong>, \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u0435\u0442\u043e\u0434 <strong>rules()<\/strong> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: <\/p>\n<pre><code class=\"php\">&lt;?php  use App\\Model\\Item; use Illuminate\\Foundation\\Http\\FormRequest; use Illuminate\\Validation\\Rule;  class StoreItemRequest extends FormRequest {     public function rules()     {         return [             'type' =&gt; ['required', Rule::in(Item::AVAILABLE_TYPES)],             'title' =&gt; 'required',             'description' =&gt; 'nullable',         ];     } } <\/code><\/pre>\n<p>\u0412 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <strong>__toString()<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0432 \u0441\u0442\u0440\u043e\u043a\u0443.<\/p>\n<p>\u0421 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432\u0441\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0412\u043e\u0442 \u0442\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043e\u0442\u0432\u0435\u0442 \u0443 \u043d\u0430\u0441:<\/p>\n<pre><code class=\"php\">&lt;?php  namespace App\\Resources;  use App\\Resources\\CachedAppJsonResource;  \/**  * @mixin \\App\\Models\\Location  *\/ class Location extends CachedAppJsonResource {     \/**      * @param  \\Illuminate\\Http\\Request  $request      * @return array      *\/     public function toArray($request)     {         return self::upSet($this, function () {             return [                 'id' =&gt; $this-&gt;id,                 'title' =&gt; $this-&gt;title,                 'location' =&gt; $this-&gt;location,                 'lat' =&gt; $this-&gt;lat,                 'lng' =&gt; $this-&gt;lng,             ];         });     } }<\/code><\/pre>\n<p><strong>upSet<\/strong> &#8212; \u044d\u0442\u043e \u043a\u043e\u0441\u0442\u044b\u043b\u044c \u0434\u043b\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 (\u043f\u0440\u0438\u0445\u0440\u0430\u043d\u0438\u0432\u0430\u0435\u043c \u0432 in-memory \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442). \u041e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0432 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0441 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438.<\/p>\n<p>\u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043a\u0430\u043a \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u043f\u043e\u043b\u044f \u0438\u0437 \u043e\u0442\u0432\u0435\u0442\u0430. \u041c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0442\u043e\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u0435\u0435: <a href=\"https:\/\/github.com\/nikic\/PHP-Parser\" rel=\"noopener noreferrer nofollow\">PhpParser<\/a>. \u0415\u0441\u0442\u044c \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f online \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0434\u0435\u0440\u0435\u0432\u0430: <a href=\"https:\/\/phpast.com\/\" rel=\"noopener noreferrer nofollow\">https:\/\/phpast.com\/<\/a> (\u0441\u043f\u0430\u0441\u0438\u0431\u043e <a class=\"mention\" href=\"\/users\/pronskiy\">@pronskiy<\/a> \u0437\u0430 \u043d\u0430\u0432\u043e\u0434\u043a\u0443).<\/p>\n<pre><code class=\"php\">&lt;?php      \/**      * @apiResponse \\App\\Resources\\Location      *\/     public function add(AddRequest $request, AddHandler $addHandler)     {         $location = $addHandler($request);          return $this-&gt;respondWithResource(new Location($location));     }<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u0441\u0435 \u043f\u0440\u043e \u0432\u0441\u0435 \u0443\u0448\u043b\u043e \u0433\u0434\u0435-\u0442\u043e 2-3 \u0434\u043d\u044f. \u041f\u043b\u044e\u0441 \u043a\u043e \u0432\u0441\u0435\u043c\u0443, \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0440\u043e\u0443\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 (\u0431\u044b\u043b\u043e -&gt; \u0441\u0442\u0430\u043b\u043e):<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b0a\/ae2\/e85\/b0aae2e85bea7df26748124b61ddeb52.png\" width=\"1819\" height=\"316\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u0441\u0447\u0435\u0442 \u0441\u0430\u043c\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0442\u043e \u0432\u043e\u0442 \u043a\u0430\u043a \u043e\u043d\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0430 (\u043a \u0441\u043e\u0436\u0435\u043b\u0435\u043d\u0438\u044e \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043d\u0430 \u043d\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0437\u044f\u043b \u0441 \u0434\u0435\u043c\u043e):<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/abd\/66b\/629\/abd66b6296d02b8a171ea2172ea6bef6.png\" width=\"1215\" height=\"851\"><figcaption><\/figcaption><\/figure>\n<p>\u0410 \u0432\u043e\u0442 \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0435\u0439\u0447\u0430\u0441:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/446\/be2\/7c6\/446be27c6470032ebcd4cf1c562ee6b5.png\" width=\"1803\" height=\"490\"><figcaption><\/figcaption><\/figure>\n<p>\u0418\u0437 \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0435\u0439 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a <strong>&#171;&#8230;&#187; <\/strong>(\u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043d\u0443\u0436\u043d\u043e \u0432 \u0440\u0435\u0441\u0443\u0440\u0441\u0435 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u043e\u043b\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u0438 \u0434\u043e\u043a\u0431\u043b\u043e\u043a\u043e\u043c \u043a \u043d\u0435\u043c\u0443)<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435\u0442 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0440\u043e\u0443\u0442\u0430 \u0438 \u0447\u0442\u043e \u043e\u043d \u0434\u0435\u043b\u0430\u0435\u0442 (\u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043a \u043c\u0435\u0442\u043e\u0434\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432)<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435\u0442 \u043a\u043e\u0434\u043e\u0432 \u043e\u0442\u0432\u0435\u0442\u0430, \u0438 \u0441\u0430\u043c\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 (\u0437\u0434\u0435\u0441\u044c \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0435\u0442, \u0438\u043b\u0438 \u043f\u0438\u0448\u0435\u0442\u0435 \u0432 \u0441\u0442\u0438\u043b\u0435 OpenAPI\/Swagger, \u0438\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u0435\u043d\u044c\u043a\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c)<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0441\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043c\u0438\u043d\u0443\u0441\u044b \u043d\u0430\u0441 \u043d\u0435 \u0441\u043c\u0443\u0449\u0430\u044e\u0442. \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f, \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u043f\u0440\u043e\u0441\u0438\u0442\u044c. API \u043d\u0435 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0435. \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u0447\u0442\u043e \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 &#171;\u043f\u0440\u043e\u0442\u0443\u0445\u0448\u0435\u0439&#187; \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0447\u0442\u043e-\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b (\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0438\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u0435, \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\/\u0443\u0434\u0430\u043b\u0438\u043b \u0440\u043e\u0443\u0442) &#8212; \u044d\u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0441\u0442\u0430\u043d\u0435\u0442 \u0432\u0438\u0434\u043d\u043e.<\/p>\n<p>\u0412\u0441\u0435\u043c \u0441\u043f\u0430\u0441\u0438\u0431\u043e.<\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/562766\/\"> https:\/\/habr.com\/ru\/post\/562766\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u041d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u0434\u044d\u0439\u043b\u0438\u043a\u043e\u0432, \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043f\u043e\u0434\u043d\u044f\u043b\u0438 \u0432\u043e\u043f\u0440\u043e\u0441 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e API \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041f\u043e \u0433\u043e\u0440\u044f\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0430\u043c \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u0448\u043b\u0438, \u0447\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u0442\u044b\u043a\u043e\u0432\u043a\u0438: \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u043e\u0444\u0438\u043a\u0441\u0438\u043b \u0431\u0430\u0433, \u043d\u043e \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043b \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u043f\u043e \u0440\u043e\u0443\u0442\u0443. \u0422\u0430\u043a \u043a\u0430\u043a \u0442\u0430\u043a\u043e\u0435 \u0443\u0436\u0435 \u0441\u043b\u0443\u0447\u0430\u043b\u043e\u0441\u044c \u043d\u0435 \u0432\u043f\u0435\u0440\u0432\u044b\u0435 &#8212; \u0431\u044b\u043b\u0430 \u0437\u0430\u0432\u0435\u0434\u0435\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0430 \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441 \u044d\u0442\u0438\u043c \u043f\u043e\u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<p>\u0416\u0434\u0430\u0442\u044c \u0434\u043e\u043b\u0433\u043e \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c, \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 <strong>PHP<\/strong> c <strong>7.2<\/strong> \u0434\u043e <strong>7.4<\/strong> &#8212; \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0438, \u0432\u043c\u0435\u0441\u0442\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u041e\u0448\u0438\u0431\u043a\u0430 \u0431\u044b\u043b\u0430 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0431\u044b\u0441\u0442\u0440\u043e &#8212; \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 <strong>UI<\/strong> \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u041f\u0420 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u0431\u044b\u0441\u0442\u0440\u043e, \u043d\u043e \u043f\u0440\u043e\u0432\u0438\u0441\u0435\u043b \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 open \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0434\u0435\u043b\u044e. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e, \u0442\u0438\u043a\u0435\u0442 \u043d\u0430\u0441\u0447\u0435\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438  \u043f\u043e\u0448\u0435\u043b \u0432 \u0440\u0430\u0431\u043e\u0442\u0443.<\/p>\n<h2>\u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u0435\u043b<\/h2>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435:<\/p>\n<ul>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 &#8212; Laravel 7<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f &#8212; Blueprint Docs<em> <\/em><a href=\"https:\/\/github.com\/M165437\/laravel-blueprint-docs\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/M165437\/laravel-blueprint-docs<\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u043d\u0435 \u0432 \u043a\u0443\u0440\u0441\u0435 \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u0442\u043e \u0441\u043c\u044b\u0441\u043b \u0442\u0430\u043a\u043e\u0439: \u0435\u0441\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b (<strong>*.apib<\/strong>), \u0441\u043e \u0441\u0432\u043e\u0438\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u043e\u043c, \u0438 \u043f\u0430\u0440\u0441\u0435\u0440 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 &#8212; <a href=\"https:\/\/github.com\/apiaryio\/drafter\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/apiaryio\/drafter<\/a>), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0447\u0438\u0442\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b. \u041f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b\u043b \u0432\u044b\u0431\u0440\u0430\u043d \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u044f \u043d\u0435 \u0437\u043d\u0430\u044e (\u0431\u044b\u043b\u043e \u0434\u043e \u043c\u0435\u043d\u044f).<\/p>\n<p>\u0418\u0437 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0433\u0443\u0433\u043b, \u0431\u044b\u043b\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0432\u0430 \u043f\u0440\u0435\u0442\u0435\u043d\u0434\u0435\u043d\u0442\u0430:<\/p>\n<ul>\n<li>\n<p>OpenAPI\/Swagger<\/p>\n<\/li>\n<li>\n<p>Laravel API Documentation Generator &#8212; <a href=\"https:\/\/github.com\/mpociot\/laravel-apidoc-generator\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/mpociot\/laravel-apidoc-generator<\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u043e\u0442\u043f\u0430\u043b \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e (\u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e) \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043e\u043a\u0431\u043b\u043e\u043a\u043e\u0432, \u0438 \u044d\u0442\u043e \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0437\u0430\u0431\u044b\u0432\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435. \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f &#8212; <a href=\"https:\/\/blog.quickadminpanel.com\/laravel-api-documentation-with-openapiswagger\/\" rel=\"noopener noreferrer nofollow\">https:\/\/blog.quickadminpanel.com\/laravel-api-documentation-with-openapiswagger\/<\/a><\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0431\u044b\u043b \u043d\u0435\u043f\u043b\u043e\u0445, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0442\u0435\u043c \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u043b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0441\u043f\u043e\u043d\u0437 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430:<\/p>\n<pre><code class=\"php\">\/**  * @apiResourceCollection  Mpociot\\ApiDoc\\Tests\\Fixtures\\UserResource  * @apiResourceModel  Mpociot\\ApiDoc\\Tests\\Fixtures\\User  *\/ public function listUsers() {     return UserResource::collection(User::all()); }  \/**  * @apiResourceCollection  Mpociot\\ApiDoc\\Tests\\Fixtures\\UserResource  * @apiResourceModel  Mpociot\\ApiDoc\\Tests\\Fixtures\\User  *\/ public function showUser(User $user) {     return new UserResource($user); }<\/code><\/pre>\n<p>\u041d\u043e \u0447\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f <strong>Request<\/strong> &#8212; \u0431\u0443\u0434\u044c \u0434\u043e\u0431\u0440 \u0440\u0430\u0441\u043f\u0438\u0448\u0438 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0447\u0442\u043e \u043a \u0447\u0435\u043c\u0443:<\/p>\n<pre><code class=\"php\">\/**  * @urlParam  id required The ID of the post.  * @urlParam  lang The language.  * @bodyParam  user_id int required The id of the user. Example: 9  * @bodyParam  room_id string The id of the room.  * @bodyParam  forever boolean Whether to ban the user forever. Example: false  * @bodyParam  another_one number Just need something here.  * @bodyParam  yet_another_param object required Some object params.  * @bodyParam  yet_another_param.name string required Subkey in the object param.  * @bodyParam  even_more_param array Some array params.  * @bodyParam  even_more_param.* float Subkey in the array param.  * @bodyParam  book.name string  * @bodyParam  book.author_id integer  * @bodyParam  book[pages_count] integer  * @bodyParam  ids.* integer  * @bodyParam  users.*.first_name string The first name of the user. Example: John  * @bodyParam  users.*.last_name string The last name of the user. Example: Doe  *\/ public function createPost() {     \/\/ ... }  \/**  * @queryParam  sort Field to sort by  * @queryParam  page The page number to return  * @queryParam  fields required The fields to include  *\/ public function listPosts() {     \/\/ ... }<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0443 <strong>Request&#8217;a <\/strong>(\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <em>Illuminate\\Foundation\\Http\\FormRequest<\/em>), \u0431\u044b\u043b\u043e \u0431\u044b \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u0418 \u0442\u0443\u0442 \u043f\u0440\u0438\u0448\u043b\u0430 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u043c\u044b\u0441\u043b\u044c: &#171;\u0410 \u043d\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434 \u043d\u0430 PHP&#8230;&#187;.<\/p>\n<p>\u0422\u0430\u043a, \u043a\u0430\u043a \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f (2 BE \u0438 2 FE), \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u043b\u044e\u0448\u043a\u0430\u043c\u0438 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043e\u0447\u043d\u044b\u0445 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u043a\u043e\u0434\u044b \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0438 \u0442\u0434). \u0418\u0434\u0435\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c. \u041f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0440\u043e\u0443\u0442\u043e\u0432 \u0438\u043c\u0435\u044e\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434: <\/p>\n<pre><code class=\"php\">&lt;?php ...     public function bulkApply(BulkApplyRequest $request, BulkApplyHandler $handler)     {         $applies = $handler(BulkApplyData::fromRequest($request), $request-&gt;user());          return $this-&gt;respondWithResource(Apply::collection($applies));     }       public function accept(StatusRequest $request, AcceptHandler $handler)     {         $apply = $handler($request-&gt;get('job_app_id'));          return $this-&gt;respondWithResource(new Apply($apply));     }<\/code><\/pre>\n<p><strong>StatusRequest<\/strong> \u0438\u043c\u0435\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"php\">&lt;?php  use Illuminate\\Foundation\\Http\\FormRequest;  class StatusRequest extends FormRequest {     public function rules()     {         return [             'app_id' =&gt; 'required|exists:apps,id',         ];     } }<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0441\u0445\u0435\u043c\u0430:<\/p>\n<ul>\n<li>\n<p>\u0411\u0435\u0440\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0440\u043e\u0443\u0442\u043e\u0432 \u0438 \u043e\u0442\u0441\u0435\u043a\u0430\u043c \u0432\u0441\u0435 \u0447\u0442\u043e \u043d\u0435 <strong>\/api\/*<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 \u0440\u043e\u0443\u0442\u0430 \u0443\u0437\u043d\u0430\u0435\u043c  <strong>Controller<\/strong> \u0438 <strong>Action<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Reflection API \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u0435\u0442\u043e\u0434\u0430 (\u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 <strong>FormRequest<\/strong>)<\/p>\n<\/li>\n<li>\n<p>\u0412 DocBlock \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0434\u043b\u044f \u043e\u0442\u0432\u0435\u0442\u0430 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <strong>JsonResource<\/strong>)<\/p>\n<\/li>\n<\/ul>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u043e\u0433\u043e<\/h2>\n<p>\u0421 \u0440\u043e\u0443\u0442\u0430\u043c\u0438 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"php\">&lt;?php  declare(strict_types=1);  namespace App\\Services;  use Illuminate\\Routing\\Route; use Illuminate\\Routing\\Router;  class RouterService {     \/** @var Router *\/     private $router;       public function __construct(Router $router)     {         $this-&gt;router = $router;     }       public function getApiRoutes(): array     {         $routes = [];         foreach ($this-&gt;router-&gt;getRoutes()-&gt;getRoutes() as $route) {             if (strpos($route-&gt;uri(), 'api\/') === 0) {                 $routes[] = $route;             }         }          usort($routes, function (Route $a, Route $b) {             return strnatcmp($a-&gt;uri(), $b-&gt;uri());         });          return $routes;     } <\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u0440\u043e\u0443\u0442\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ul>\n<li>\n<p>Auth<\/p>\n<ul>\n<li>\n<p>\/api\/auth\/login<\/p>\n<\/li>\n<li>\n<p>\/api\/auth\/logout<\/p>\n<\/li>\n<li>\n<p>\/api\/auth\/register<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u0412\u043e\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435:<\/p>\n<pre><code class=\"php\">&lt;?php      public function parseRoutes(array $routes): array     {         $rows = [];         foreach ($routes as $group =&gt; $items) {             $rows[$group] = [];             foreach ($items as $route) {                 $tmp = [                     'uri' =&gt; $route-&gt;uri(),                     'methods' =&gt; $route-&gt;methods(),                     'isGuest' =&gt; in_array('guest', $route-&gt;middleware()),                 ];                  $reflection = new ReflectionClass($route-&gt;getController());                  $methodName = Str::parseCallback($route-&gt;getAction('uses'))[1];                 $reflectionMethod = $reflection-&gt;getMethod($methodName);                  $requestParam = $this-&gt;getRequestParam($reflectionMethod);                 $tmp['requestRules'] = $this-&gt;wrapRequestRules($requestParam-&gt;rules());                  $response = $this-&gt;getResponse($reflectionMethod);                 $tmp['response'] = $this-&gt;wrapResponse($response);                  $rows[$group][] = $tmp;             }         }          return $rows;     }<\/code><\/pre>\n<p><strong>isGuest<\/strong> \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0444\u043b\u0430\u0433\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u041d\u0430 17 \u0441\u0442\u0440\u043e\u043a\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. 20 &#8212; 21 \u0441\u0442\u0440\u043e\u043a\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. 23 &#8212; 24 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0440\u0435\u0441\u043f\u043e\u043d\u0437\u043e\u043c.<\/p>\n<p>\u041f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 <strong>FormRequest<\/strong>, \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u0435\u0442\u043e\u0434 <strong>rules()<\/strong> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: <\/p>\n<pre><code class=\"php\">&lt;?php  use App\\Model\\Item; use Illuminate\\Foundation\\Http\\FormRequest; use Illuminate\\Validation\\Rule;  class StoreItemRequest extends FormRequest {     public function rules()     {         return [             'type' =&gt; ['required', Rule::in(Item::AVAILABLE_TYPES)],             'title' =&gt; 'required',             'description' =&gt; 'nullable',         ];     } } <\/code><\/pre>\n<p>\u0412 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <strong>__toString()<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0432 \u0441\u0442\u0440\u043e\u043a\u0443.<\/p>\n<p>\u0421 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432\u0441\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0412\u043e\u0442 \u0442\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043e\u0442\u0432\u0435\u0442 \u0443 \u043d\u0430\u0441:<\/p>\n<pre><code class=\"php\">&lt;?php  namespace App\\Resources;  use App\\Resources\\CachedAppJsonResource;  \/**  * @mixin \\App\\Models\\Location  *\/ class Location extends CachedAppJsonResource {     \/**      * @param  \\Illuminate\\Http\\Request  $request      * @return array      *\/     public function toArray($request)     {         return self::upSet($this, function () {             return [                 'id' =&gt; $this-&gt;id,                 'title' =&gt; $this-&gt;title,                 'location' =&gt; $this-&gt;location,                 'lat' =&gt; $this-&gt;lat,                 'lng' =&gt; $this-&gt;lng,             ];         });     } }<\/code><\/pre>\n<p><strong>upSet<\/strong> &#8212; \u044d\u0442\u043e \u043a\u043e\u0441\u0442\u044b\u043b\u044c \u0434\u043b\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 (\u043f\u0440\u0438\u0445\u0440\u0430\u043d\u0438\u0432\u0430\u0435\u043c \u0432 in-memory \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442). \u041e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0432 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0441 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438.<\/p>\n<p>\u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043a\u0430\u043a \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u043f\u043e\u043b\u044f \u0438\u0437 \u043e\u0442\u0432\u0435\u0442\u0430. \u041c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0442\u043e\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u0435\u0435: <a href=\"https:\/\/github.com\/nikic\/PHP-Parser\" rel=\"noopener noreferrer nofollow\">PhpParser<\/a>. \u0415\u0441\u0442\u044c \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f online \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0434\u0435\u0440\u0435\u0432\u0430: <a href=\"https:\/\/phpast.com\/\" rel=\"noopener noreferrer nofollow\">https:\/\/phpast.com\/<\/a> (\u0441\u043f\u0430\u0441\u0438\u0431\u043e <a class=\"mention\" href=\"\/users\/pronskiy\">@pronskiy<\/a> \u0437\u0430 \u043d\u0430\u0432\u043e\u0434\u043a\u0443).<\/p>\n<pre><code class=\"php\">&lt;?php      \/**      * @apiResponse \\App\\Resources\\Location      *\/     public function add(AddRequest $request, AddHandler $addHandler)     {         $location = $addHandler($request);          return $this-&gt;respondWithResource(new Location($location));     }<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u0441\u0435 \u043f\u0440\u043e \u0432\u0441\u0435 \u0443\u0448\u043b\u043e \u0433\u0434\u0435-\u0442\u043e 2-3 \u0434\u043d\u044f. \u041f\u043b\u044e\u0441 \u043a\u043e \u0432\u0441\u0435\u043c\u0443, \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0440\u043e\u0443\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 (\u0431\u044b\u043b\u043e -&gt; \u0441\u0442\u0430\u043b\u043e):<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u0441\u0447\u0435\u0442 \u0441\u0430\u043c\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0442\u043e \u0432\u043e\u0442 \u043a\u0430\u043a \u043e\u043d\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0430 (\u043a \u0441\u043e\u0436\u0435\u043b\u0435\u043d\u0438\u044e \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043d\u0430 \u043d\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0437\u044f\u043b \u0441 \u0434\u0435\u043c\u043e):<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0410 \u0432\u043e\u0442 \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0435\u0439\u0447\u0430\u0441:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0418\u0437 \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0435\u0439 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a <strong>&#171;&#8230;&#187; <\/strong>(\u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043d\u0443\u0436\u043d\u043e \u0432 \u0440\u0435\u0441\u0443\u0440\u0441\u0435 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u043e\u043b\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u0438 \u0434\u043e\u043a\u0431\u043b\u043e\u043a\u043e\u043c \u043a \u043d\u0435\u043c\u0443)<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435\u0442 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0440\u043e\u0443\u0442\u0430 \u0438 \u0447\u0442\u043e \u043e\u043d \u0434\u0435\u043b\u0430\u0435\u0442 (\u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043a \u043c\u0435\u0442\u043e\u0434\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432)<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435\u0442 \u043a\u043e\u0434\u043e\u0432 \u043e\u0442\u0432\u0435\u0442\u0430, \u0438 \u0441\u0430\u043c\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 (\u0437\u0434\u0435\u0441\u044c \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0435\u0442, \u0438\u043b\u0438 \u043f\u0438\u0448\u0435\u0442\u0435 \u0432 \u0441\u0442\u0438\u043b\u0435 OpenAPI\/Swagger, \u0438\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u0435\u043d\u044c\u043a\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c)<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0441\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043c\u0438\u043d\u0443\u0441\u044b \u043d\u0430\u0441 \u043d\u0435 \u0441\u043c\u0443\u0449\u0430\u044e\u0442. \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f, \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u043f\u0440\u043e\u0441\u0438\u0442\u044c. API \u043d\u0435 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0435. \u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u0447\u0442\u043e \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 &#171;\u043f\u0440\u043e\u0442\u0443\u0445\u0448\u0435\u0439&#187; \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0447\u0442\u043e-\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u043b (\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0438\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u0435, \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\/\u0443\u0434\u0430\u043b\u0438\u043b \u0440\u043e\u0443\u0442) &#8212; \u044d\u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0441\u0442\u0430\u043d\u0435\u0442 \u0432\u0438\u0434\u043d\u043e.<\/p>\n<p>\u0412\u0441\u0435\u043c \u0441\u043f\u0430\u0441\u0438\u0431\u043e.<\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/562766\/\"> https:\/\/habr.com\/ru\/post\/562766\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-324913","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/324913","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=324913"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/324913\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=324913"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=324913"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=324913"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}