Key insights
- Client-side validation exists for speed, not safety. Green checks and inline errors fire with 0 network calls because catching mistakes instantly is a frontend job.
- The server re-runs every check the client already did, only stricter. Never trust the client: anyone can forge a request, so re-compute the total from your own catalog instead of believing the price the browser sent.
- Wrap the related writes (order, items, inventory, payment) in one transaction. If a single row fails, every row rolls back, so an order never lands half-written. All of it, or none of it.
- When the response returns, repaint the UI with server truth, the real order ID the server created, not a value you guessed locally.
- Optimistic UI fits cheap, reversible actions: a like, a favorite, a rename can repaint instantly and reconcile in the background. Money is different, so hold the spinner until the server actually confirms.
Do / Don't
- Do: Validate on the client for speed and on the server for trust, never one instead of the other.
- Do: Re-compute prices and totals server-side from your own source of truth.
- Do: Wrap multi-row writes in one transaction so any failure rolls back the whole thing.
- Don't: Trust values the client sends, including the price, since a request is trivial to forge.
- Don't: Reach for optimistic UI on payments or other irreversible actions; make them earn the spinner.