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.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 client3
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 2015
API client parses the response
response.json() returns the new user object back to handleCreate6
State updates, React re-renders
setUsers(prev => [...prev, newUser]) adds the user. React re-renders the list. Maria appears on screen.fetch() → FastAPI → response → state update → re-render.
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