Laravel — це досить гарний PHP-фреймворк, який надає багато корисних функцій. Одним з них є клас Ресурс. Дуже часто ми отримуємо якісь дані з колишньої бази даних і відправляємо їх клієнту нашого додатку. Відправка всієї моделі - дуже поганий варіант, і на це є багато причин:
- Ми, мабуть, не хочемо розкривати структуру наших моделей
- Деякі дані можуть бути конфіденційними – можливо, наш клієнт не буде використовувати ці поля, але кожен користувач зможе подивитися запит, відповідь і отримати ці дані
- Багатьом клієнтам (наприклад, мобільним пристроям) не потрібні всі дані
Без класу Resource нам доводиться створювати власний клас і робити деякі перетворення, готувати дані з бази даних для клієнтів. Якщо ми вирішимо використовувати вбудований Ресурс, це буде набагато, набагато простіше. Нам залишається тільки повернути такі екземпляри класів і передати наші дані в конструктор, а потім написати, які поля ми дійсно хочемо використовувати. Є простий приклад ресурсу Laravel, який підготує наші дані для відправки у форматі JSON:
declare(strict_types=1);
namespace App\Modules\MyModule\Resources;
use Illuminate\Http\Resources\Json\Resource;
class MyModelResource extends Resource
{
/**
* @var MyModel
*/
public $resource;
public function toArray($request)
{
return [
“id” => $this->resource->getKey(),
“name” => $this->resource->my_model_name,
“count” => $this->resource->my_model_attribute,
(...)
];
}
}
Цей коментар з $var MyModel є необов'язковим, але допомагає деяким IDE розпізнати, яку модель ми будемо використовувати в нашому ресурсі. І в нашому контролері є застосування:
public function getModel(Request $request): JsonResponse
{
// here some code for get model (or inject it with route)
$model = MyModel::find($request->id);
return response()->json(
new MyModelResource($model)
);
}
Просто, чисто і елегантно, адже ми трансформуємо нашу модель в окремому місці. Якщо це необхідно, ми можемо змінити наші дані більш складним чином, без проблем. Ми також можемо використовувати... Ресурс всередині ресурсу, тому можна зробити щось на кшталт цього:
public function toArray($request)
{
return [
"id" => $this->resource->getKey(),
"name" => $this->resource->my_model_name,
"relation" => new MyModelRelationResource($this->resource->relation),
(...)
];
}
Колекційні ресурси
Що робити, якщо у нас багато елементів і ми хочемо надіслати їх у форматі JSON? Це також не проблема, тому що для цього ми можемо використовувати вбудований клас ResourceCollection. Є ще один приклад:
declare(strict_types=1);
namespace App\Modules\MyModule\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class MyModuleCollectionResource extends ResourceCollection
{
public function toArray($request)
{
return MyModuleResource::collection($this->collection);
}
}
Звичайно, ми можемо модифікувати або трансформувати колекцію так само, як і в звичайному Resource, просто масив відповідей. Використання в контролері:
public function getModels(Request $request): JsonResponse
{
$models = MyModel::all();
return response()->json(
new MyModuleCollectionResource($models)
);
}
Як бачите, він дуже простий у використанні, дозволяє нам зробити все більш організованим і вирішити багато питань.