При создании API вам может потребоваться уровень преобразования, который находится между вашими моделями Eloquent и ответами JSON, которые фактически возвращаются пользователям вашего приложения. Например, вы можете захотеть отображать определенные атрибуты для подмножества пользователей, а не других, или вы можете всегда включать определенные отношения в JSON-представление ваших моделей. Классы ресурсов Eloquent позволяют легко и выразительно преобразовывать ваши модели и коллекции моделей в JSON. Конечно, вы всегда можете преобразовать модели или коллекции Eloquent в JSON, используя их методы toJson; однако ресурсы Eloquent обеспечивают более детальный и надежный контроль над сериализацией JSON ваших моделей и их взаимосвязями, и делают возможным множественное использование одного ресруса.
Чтобы сгенерировать класс ресурсов, вы можете использовать Artisan-команду make:resource
. По умолчанию ресурсы будут помещены в каталог app/Http/Resources
приложения. Ресурсы расширяют класс Illuminate\Http\Resources\Json\JsonResource
:
php artisan make:resource UserResource
Помимо создания ресурсов, преобразующих отдельные модели, вы можете создавать ресурсы, отвечающие за преобразование коллекций моделей. Это позволяет вашим ответам JSON включать ссылки и другую метаинформацию, имеющую отношение ко всей коллекции данного ресурса. Чтобы создать коллекцию ресурсов, вы должны использовать флаг --collection
при создании ресурса. Или включение слова Collection
в имя ресурса укажет Laravel, что он должен создать ресурс коллекции. Ресурсы коллекции расширяют класс Illuminate\Http\Resources\Json\ResourceCollection
:
php artisan make:resource User --collection php artisan make:resource UserCollection
Каждый класс ресурсов определяет метод toArray, который возвращает массив атрибутов, которые должны быть преобразованы в JSON, когда ресурс возвращается в качестве ответа от метода маршрута или контроллера.
namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; class UserResource extends JsonResource { /** * Transform the resource into an array. * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; } }
Обратите внимание, что мы можем получить доступ к свойствам модели непосредственно из переменной $this
. Это связано с тем, что класс ресурсов автоматически передает свойства и методы доступа к базовой модели для удобного доступа. Как только ресурс определен, он может быть возвращен из маршрута или контроллера. Причём его вызов может быть либо множественным, либо одиночным.
Одиночный вызов ресурса через конструктор:
Route::get('/user/{id}', function ($id) { return new UserResource(User::findOrFail($id)); });
Множественный вызов ресруса с помощью метода collection
Route::get('/users', function () { return UserResource::collection(User::all()); });
Связи в ресурсах
Если вы хотите включить связанные ресурсы в свой ответ, вы можете добавить их в массив, возвращаемый методом toArray вашего ресурса. В этом примере мы будем использовать метод коллекции ресурса PostResource, чтобы добавить сообщения блога пользователя в ответ ресурса:
use App\Http\Resources\PostResource; /** * Transform the resource into an array. * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email, 'posts' => PostResource::collection($this->posts), 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]; }