Skip to main content

The problem: silent mismatches

Your FastAPI backend defines data shapes with Pydantic models. Your React frontend sends and receives that data. If they disagree on the shape, things break — often silently.
The backend rejects it with a 422 error, but the error message isn’t always obvious. Or worse — the frontend reads a field that the backend renamed, and you get undefined rendering on screen with no error at all.

Keep your shapes in sync

The simplest approach: document the expected shapes in your API client file.
This is documentation, not enforcement — but it tells any developer exactly what the backend expects.

Runtime validation

For critical operations, validate before sending:
Validate on the frontend for instant user feedback. But always validate on the backend too — frontend validation can be bypassed. Pydantic handles backend validation automatically. Think of frontend validation as a UX feature, not a security feature.

Consistent API response shapes

Design your backend responses to be predictable. When every endpoint follows the same pattern, the frontend code becomes simpler.
The frontend can rely on these patterns:
  • GET list → always an array (even if empty)
  • GET single → the object, or a 404 error
  • POST → returns the created object (with its new id)
  • PUT → returns the updated object
  • DELETE → returns nothing (204 status)
The companion repo keeps the backend simple and uses UserCreate for both create and update operations. A separate UserUpdate model (with optional fields) is a common next step once you want partial updates.

Handling backend validation errors

FastAPI returns 422 errors with a structured format. Parse them in your API client:
FastAPI validation errors return an array of { loc: ["body", "email"], msg: "field required", type: "missing" } objects. The code above extracts the field name and message into a simple { email: "field required" } format that your form components can display directly.

TypeScript preview

If you want true compile-time type safety, TypeScript is the answer. Here’s a taste:
TypeScript catches the username vs name mismatch at development time, before any code runs. This is the gold standard for full-stack type safety.
You don’t need TypeScript to build full-stack apps. JavaScript with good documentation and runtime validation works fine, especially when you’re learning. But once you’re comfortable with JavaScript, TypeScript is a natural next step — it catches an entire category of bugs automatically.

What’s next?

Your frontend and backend are connected, organized, and type-aware. Now let’s build the four CRUD operations that make up every data-driven application — starting with Create.

Create operation

Build a form that sends data to your FastAPI backend and creates a new record