0
0
Lập trình
Thaycacac
Thaycacac thaycacac

Hướng Dẫn Toàn Diện về Laravel Resources và Collections

Đăng vào 4 tháng trước

• 6 phút đọc

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 Copy
<?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 Copy
<?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 Copy
<?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 Copy
{
  "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 Copy
<?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 Copy
<?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 Copy
<?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 Copy
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ẽ:

  1. Tự động ánh xạ từng bài viết qua ArticleResource
  2. Bảo tồn metadata phân trang (trang hiện tại, tổng số, liên kết, v.v.)
  3. 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 Copy
{
  "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 Copy
{
  "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

  1. Sử dụng lớp final cho resources khi bạn không có kế hoạch mở rộng chúng.
  2. Khai báo kiểu nghiêm ngặt để đảm bảo an toàn kiểu tốt hơn.
  3. Xử lý các mối quan hệ tùy chọn một cách nhẹ nhàng với optional().
  4. Sử dụng định dạng ISO 8601 cho ngày tháng trong API.
  5. 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.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào