Product CRUD: backend contract mỏng
Backend sample không cố trình diễn architecture pattern. Nó chỉ tạo một contract đủ tốt để Frontend có thể dùng Inertia đúng cách.Routes
routes/web.php
Migration
database/migrations/xxxx_xx_xx_create_products_table.php
price dùng integer để sample không mang thêm vấn đề floating-point vào phần Frontend.
Index: thiết kế prop theo cost
app/Http/Controllers/ProductController.php
products dùng closure
Closure giúp server trì hoãn evaluate prop tới khi Inertia biết request hiện tại có cần key đó hay không. Khi Frontend dùng partial reload, query không cần thiết có thể được bỏ qua.
filters được canonicalize ở server
Frontend không tự suy luận default. Server trả đúng state cuối cùng:
stats là deferred
Stats hữu ích nhưng không cần để người dùng bắt đầu thao tác với bảng. Vì vậy nó không nên block first paint.
rescue: true phù hợp khi stats hỏng không được phép làm cả trang CRUD thất bại.
Store / update: validation vẫn thuộc server
app/Http/Requests/StoreProductRequest.php
Mutation và redirect
setProducts([...products, response.data]) sau create. Server response sau redirect mới là canonical state.
Toggle cho optimistic UX
Shared flash
app/Http/Middleware/HandleInertiaRequests.php
recentlySuccessful phù hợp hơn với feedback cục bộ của một form vẫn còn ở cùng page.