Skip to main content

The complete app

Let’s put everything together. This is a complete user management app — the same patterns you’ve learned across the last several lessons, wired together into one working application.
This walkthrough is a JS-first teaching version of the patterns. The companion repo is more production-structured: backend routes live in backend/routers/users.py, models in backend/models.py, the web client is TypeScript (.ts/.tsx with frontend/src/types.ts and frontend/src/api/users.ts), and there’s also a mobile/ Expo app using the same FastAPI API.

Backend — the full API

The companion repo uses UserCreate for both create and update. This walkthrough shows a separate UserUpdate model to demonstrate a common partial-update pattern you’ll likely adopt later.
Five endpoints. Five HTTP methods. That’s the entire backend for a CRUD app.

Frontend — the API client

Frontend — the components

Frontend — the main page

Tracing the data flow

Let’s trace what happens when a user clicks “Add User”:
1

User fills form and submits

CreateUserForm calls onSubmit({ name: "Maria Lopez", email: "maria@example.com" })
2

App.jsx handles the create

handleCreate calls createUser(formData) from the API client
3

API client sends the request

fetch("http://localhost:8000/api/users", { method: "POST", body: ... })
4

FastAPI receives and validates

Pydantic validates the data. If valid, creates the user and returns { id: 3, name: "Maria Lopez", email: "maria@example.com" } with status 201
5

API client parses the response

response.json() returns the new user object back to handleCreate
6

State updates, React re-renders

setUsers(prev => [...prev, newUser]) adds the user. React re-renders the list. Maria appears on screen.
Every CRUD operation follows this same flow: Component → API client → fetch() → FastAPI → response → state update → re-render.
When debugging, trace the flow step by step. Add console.log at each stage to see where data gets lost or transformed incorrectly. The Network tab in DevTools shows the actual HTTP requests and responses.

What’s next?

You’ve seen the complete app. Now let’s polish it — handling errors gracefully across the entire stack.

Error handling across the stack

Handle errors consistently from FastAPI to React for a great user experience