Giới thiệu
Laravel Resources cung cấp một phương pháp mạnh mẽ và tinh tế để chuyển đổi các mô hình Eloquent và bộ sưu tập mô hình thành các phản hồi JSON. Dù bạn đang xây dựng một REST API hay cần đầu ra dữ liệu có cấu trúc, resources cho phép bạn kiểm soát toàn bộ cách dữ liệu được trình bày cho người tiêu dùng.
Trong hướng dẫn toàn diện này, chúng ta sẽ khám phá cả Resources đơn lẻ và Resource Collections, bao gồm việc xử lý phân trang tự động trong Laravel 12.
Laravel Resources là gì?
Laravel Resources hoạt động như một lớp chuyển đổi giữa các mô hình Eloquent và các phản hồi JSON mà người dùng ứng dụng của bạn nhận được. Chúng cho phép bạn chuyển đổi các mô hình và bộ sưu tập mô hình một cách biểu cảm và dễ dàng thành JSON.
Triển khai Resource cơ bản
Hãy bắt đầu với một ArticleResource đơn giản để chuyển đổi một mô hình Article:
Mô hình
Đầu tiên, đây là mô hình Article cơ bản của chúng ta:
php
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use HasFactory;
protected $fillable = ['title', 'body', 'published_at'];
protected $casts = ['published_at' => 'datetime'];
}
Resource
php
<?php
declare(strict_types=1);
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
final class ArticleResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'body' => $this->body,
'published_at' => optional($this->published_at)?->toIso8601String(),
'created_at' => $this->created_at->toIso8601String(),
];
}
}
Sử dụng Resource
Trong controller của bạn, bạn có thể sử dụng resource như sau:
php
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Http\Resources\ArticleResource;
use App\Models\Article;
final class ArticleController extends Controller
{
public function show(Article $article): ArticleResource
{
return new ArticleResource($article);
}
}
Điều này sẽ trả về một phản hồi JSON như sau:
json
{
"data": {
"id": 1,
"title": "Understanding Laravel Resources",
"body": "Laravel Resources provide a powerful way...",
"published_at": "2024-01-15T10:30:00Z",
"created_at": "2024-01-15T08:00:00Z"
}
}
Resource Collections với Phân Trang Tự Động
Khi làm việc với nhiều mô hình, Laravel cung cấp Resource Collections. Đây là nơi mà tính năng tự động ánh xạ của Laravel 12 thực sự tỏa sáng:
Collection Resource
php
<?php
declare(strict_types=1);
namespace App\Http\Resources;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use JsonSerializable;
final class ArticleCollection extends JsonResource
{
/** Tự động ánh xạ từng mục với ArticleResource */
public string $collects = ArticleResource::class;
/** Bảo tồn cấu trúc mặc định (dữ liệu + liên kết + meta nếu có phân trang) */
public function toArray(Request $request): array|JsonSerializable|Arrayable
{
return parent::toArray($request);
}
public function with($request): array
{
return [
'meta_extra' => ['generate_at' => now()->toIso8601String()]
];
}
}
Sử dụng Collection với Phân Trang
php
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Http\Resources\ArticleCollection;
use App\Models\Article;
final class ArticleController extends Controller
{
public function index(): ArticleCollection
{
return new ArticleCollection(
Article::query()->latest()->paginate(10)
);
}
}
Thiết lập Routes
php
<?php
use App\Http\Controllers\ArticleController;
use Illuminate\Support\Facades\Route;
Route::get('/articles', [ArticleController::class, 'index'])->name('articles.index');
Route::get('/articles/{article}', [ArticleController::class, 'show'])->name('articles.show');
Điều kỳ diệu: Tính Năng Tự Động của Laravel 12
Sự đổi mới chính trong ArticleCollection là thuộc tính $collects:
php
public string $collects = ArticleResource::class;
Điều này cho Laravel biết để tự động bọc mỗi mục trong bộ sưu tập với lớp resource đã chỉ định. Khi bạn truyền một bộ sưu tập đã phân trang vào resource này, Laravel sẽ:
- Tự động ánh xạ từng bài viết qua
ArticleResource - Bảo tồn metadata phân trang (trang hiện tại, tổng số, liên kết, v.v.)
- Duy trì cấu trúc mặc định của Laravel với các khóa
data,links, vàmeta
Cấu trúc Phản hồi
Phản hồi Resource Đơn
json
{
"data": {
"id": 1,
"title": "Understanding Laravel Resources",
"body": "Laravel Resources provide a powerful way...",
"published_at": "2024-01-15T10:30:00Z",
"created_at": "2024-01-15T08:00:00Z"
}
}
Phản hồi Bộ Sưu Tập Đã Phân Trang
json
{
"data": [
{
"id": 1,
"title": "Understanding Laravel Resources",
"body": "Laravel Resources provide a powerful way...",
"published_at": "2024-01-15T10:30:00Z",
"created_at": "2024-01-15T08:00:00Z"
},
{
"id": 2,
"title": "Another Article",
"body": "Content of another article...",
"published_at": "2024-01-16T14:20:00Z",
"created_at": "2024-01-16T12:00:00Z"
}
],
"links": {
"first": "http://example.com/articles?page=1",
"last": "http://example.com/articles?page=5",
"prev": null,
"next": "http://example.com/articles?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 5,
"path": "http://example.com/articles",
"per_page": 10,
"to": 10,
"total": 50
},
"meta_extra": {
"generate_at": "2024-01-15T15:45:30Z"
}
}
Lợi ích Chính
1. Chuyển Đổi Mục Tự Động
Thuộc tính $collects loại bỏ nhu cầu phải lặp qua từng mục và áp dụng các chuyển đổi.
2. Bảo Tồn Phân Trang
Laravel tự động duy trì tất cả metadata phân trang, bao gồm các liên kết và thông tin meta.
3. Cấu Trúc Nhất Quán
Các phản hồi API của bạn duy trì cấu trúc nhất quán cho dù trả về các mục đơn lẻ hay bộ sưu tập.
4. Có Thể Mở Rộng
Bạn có thể dễ dàng thêm metadata bổ sung bằng cách sử dụng phương thức with() mà không làm gián đoạn cấu trúc cốt lõi.
5. An Toàn Kiểu
Với kiểu dữ liệu đúng, bạn sẽ nhận được hỗ trợ IDE tốt hơn và phát hiện lỗi sớm hơn.
Thực Hành Tốt Nhất
- Sử dụng lớp final cho resources khi bạn không có kế hoạch mở rộng chúng.
- Khai báo kiểu nghiêm ngặt để đảm bảo an toàn kiểu tốt hơn.
- Xử lý các mối quan hệ tùy chọn một cách nhẹ nhàng với
optional(). - Sử dụng định dạng ISO 8601 cho ngày tháng trong API.
- Giữ cho các chuyển đổi đơn giản - logic phức tạp nên nằm trong mô hình hoặc lớp dịch vụ.
Kết luận
Laravel Resources và Collections cung cấp một giải pháp tinh tế cho việc chuyển đổi phản hồi API. Tính năng tự động của Laravel 12 làm cho việc làm việc với dữ liệu đã phân trang trở nên liền mạch trong khi vẫn duy trì tính linh hoạt cho việc tùy chỉnh.
Bằng cách tận dụng thuộc tính $collects và cấu trúc resource hợp lý, bạn có thể xây dựng các API mạnh mẽ, nhất quán với ít mã hơn trong khi tận dụng các tính năng phân trang mạnh mẽ của Laravel.
Cho dù bạn đang xây dựng một REST API đơn giản hay một lớp chuyển đổi dữ liệu phức tạp, Laravel Resources cung cấp sự cân bằng hoàn hảo giữa sự đơn giản và sức mạnh cho nhu cầu của ứng dụng của bạn.