Trong Laravel, chúng ta có thể custom lại API Resources trả dữ liệu về phía Client một cách linh hoạt hơn, đồng thời giúp quản lý source code maintain hơn. Đó chính là khi ta sử dụng Resource & Collection trong Laravel
php artisan make:resource Post --collection
php artisan make:resource PostCollection
php artisan make:resource PostResource
Nếu bạn trả dữ liệu về một mảng data thì dùng Collection
Còn nếu trả về một data của một post được chỉ định cụ thể, thì dùng Resource
Dưới đây là phần mình custom lại Resource
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Auth;
class PostResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
// return parent::toArray($request);
return [
'id' => $this->id,
'keyword' => $this->keyword,
'router' => $request->route()->named('posts.show'),
'user' => $request->user(),
// Kiếm tra điều kiện nếu $request là "posts.show" thi chiều hiện thị thuộc tính "image"
'image' => $this->when(
$request->route()->named('posts.show'),
$this->image
),
// Nếu user có quyền "admin.posts.show" thì ta cho hiện thị thuộc tính "content"
'content' => $this->when(
Auth::guard('api')->user()?->can('admin.posts.show'),
$this->content
),
'categories' => new CategoryResource($this->whenLoaded('categories')),
];
}
}
Các bạn thấy trên mình có dùng điều kiện when() & whenLoaded()
+ Tại sự kiện when(), mình bắt điều kiện nếu user() có permission (quyền) thì mới hiện thị cột thuộc tính field ra, ngược lại thì không hiện thị
+ Còn whenLoaded('categories') nó sẽ gọi mối quan hệ many-to-many với Post. Có nghĩa là Post có nhiều Category, Category có nhiều Post , cái này mình thiết lập trong Model (Post, Category)
Sử dụng Resource trong Controller như sau:
public function show(string $id)
{
// Ghi đề guard 'api' thay với 'web', để check Laravel Permission
config(['auth.defaults.guard' => 'web']);
$post = \App\Models\Post::with('categories')->find($id);
return new PostResource($post);
}
Trên là cách mà mình xử lý dữ liệu trả về cho Client. Các bạn có thể thử nhé