FastAPI Basics: Build Your First Web API
Responses, Errors and Docs
In this lesson you will
- Raise HTTPException for expected errors
- Choose meaningful status codes
- Improve the generated OpenAPI documentation
Introduction
A good API tells clients clearly what happened. That means correct status codes, helpful error messages, and documentation that matches reality. FastAPI does most of this automatically, and you add the rest.
Status codes in brief
| Range | Meaning | Examples |
|---|---|---|
| 2xx | Success | 200 OK, 201 Created, 204 No Content |
| 4xx | The client made a mistake | 400, 401 Unauthorized, 403 Forbidden, 404 Not Found, 422 validation error |
| 5xx | The server failed | 500 Internal Server Error |
Clients rely on these codes. Returning 200 with an error message inside is confusing.
Raising errors
For expected problems, such as a missing record, raise HTTPException.
Python
from fastapi import HTTPException
@app.get("/library/{book_id}", response_model=BookOut)
def library_book(book_id: int):
if book_id not in BOOKS:
raise HTTPException(status_code=404, detail="Book not found")
return BOOKS[book_id]When the book exists, the response is 200 {"id": 1, "title": "Dune", "year": 1965}. When it does not, the response is:
JSON
{"detail": "Book not found"}with status 404. Both responses came from running this code.
Quick quiz
Which approach is better when a requested record does not exist?
Do not leak internals
Error messages are visible to anyone who calls your API. Write messages for users, not stack traces. Do not reveal database details, file paths or whether a secret value exists. Unexpected errors become a 500 response. Log the details on the server, but keep them out of the response.
Response models and extra status codes
response_model filters and documents the output. You can also document alternative responses:
Python
@app.get(
"/library/{book_id}",
response_model=BookOut,
responses={404: {"description": "No book with that id"}},
)
def library_book(book_id: int): ...Make the docs useful
FastAPI turns your code into documentation, and you can enrich it:
Python
app = FastAPI(
title="Library API",
description="Look up and add books.",
version="1.0.0",
)
@app.post("/books", tags=["books"], summary="Add a book")
def create_book(book: BookIn):
"""Create a book. The id is assigned by the server."""title,descriptionandversionappear at the top of/docs.- Tags group endpoints.
- The function docstring becomes the description.
- Field
description=and examples appear in the schema.
Check /openapi.json. For the code in this course it lists the paths /, /books, /books/{book_id}, /items, /library/{book_id} and /search.
Practical habits
- Keep one clear error format for the whole API.
- Use plural nouns for collections, such as
/books, and IDs in the path,/books/42. - Version the API when you make breaking changes, for example
/v1/books. - Never return secrets, such as password hashes, in any response.
- Test with
/docswhile you develop.
Try it yourself
Add a DELETE endpoint for books that returns 204 on success and 404 when the book does not exist. Add tags and a docstring, then check how it appears in /docs.
Summary
- Use correct status codes, and raise HTTPException for expected errors with clear, safe messages.
- Response models and the responses option shape and document the output.
- Titles, tags and docstrings turn the generated OpenAPI docs into real documentation.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.
Sources and further reading