Skip to main content

Product CRUD: full sức mạnh Inertia.js

Đây là sample trung tâm của phần Samples & Thực chiến. Ta chỉ dùng một model Product rất đơn giản để phần lớn sự chú ý nằm ở Frontend và runtime model của Inertia.
Sample này target Inertia.js v3 + Laravel + React + TypeScript. Toàn bộ source companion nằm trong examples/product-crud/ để bạn copy từng file vào project thật.

Mục tiêu cuối cùng

Sau khi hoàn thành, một màn hình CRUD duy nhất sẽ minh họa gần như toàn bộ nhóm capability Inertia thường dùng trong ứng dụng business:

Model cố tình đơn giản

Không cần Repository, Service, DTO hay API layer chỉ để làm sample. Mục tiêu là nhìn rõ mental model:

Điều quan trọng nhất: Inertia không biến app thành REST API

CRUD này không cần viết:
rồi tự dựng client-side store, router, API error mapper và cache layer riêng. Thay vào đó:
Laravel vẫn sở hữu routing, validation, authorization và redirect. React sở hữu interaction/UI state. Inertia là protocol nối hai phía.

Kiến trúc state

Đây là rule quan trọng nhất của sample:
Nếu bạn đưa toàn bộ filter vào một global client store, bạn đang chống lại lợi thế lớn nhất của Inertia: server state và URL có thể tiếp tục là source of truth.

Cấu trúc source companion

Luồng Index

Luồng Create/Edit

Luồng Optimistic toggle

Đây là nơi optimistic update phù hợp: thay đổi nhỏ, reversible và dễ xác định expected state. Không nên mặc định optimistic cho mọi mutation.

Nên đọc theo thứ tự

1. Backend contract

Backend mỏng, props có chủ đích và redirect flow đúng kiểu Inertia.

2. Index frontend

Search, filter, sort, pagination, partial reload, deferred, prefetch và optimistic update.

3. Form frontend

useForm đầy đủ: validation, dirty, loading, cancel, remember và transform.

4. Upload ảnh

Preview, progress, validation, replace/remove ảnh và multipart method spoofing.

5. Advanced UX

Tại sao từng capability được chọn và các failure mode production.

Definition of Done

CRUD chỉ được xem là “đủ để học Inertia” khi người đọc giải thích được vì sao:
  • filter phải ở URL thay vì local-only state;
  • partial reload chỉ nên request prop cần đổi;
  • deferred prop không nên chứa dữ liệu bắt buộc cho first paint;
  • prefetch chỉ hữu ích cho navigation có xác suất xảy ra cao;
  • optimistic update cần rollback semantics rõ;
  • validation vẫn nên ở server;
  • mutation thành công nên redirect thay vì client tự vá mọi state;
  • preserveState không phải lý do để giữ state sai ownership.

Tài liệu chính thức

Nội dung thực chiến trong bài được xây dựng dựa trên API và nguyên lý của Inertia.js v3 Documentation. Khi áp dụng vào dự án, hãy đối chiếu API cụ thể với tài liệu chính thức theo phiên bản bạn đang sử dụng.