Your first GET route

We set up the layout. Now let us put something in it. The smallest useful endpoint is a health check: a GET route that returns a static status. It sounds trivial, but it introduces every piece of FastAPI syntax you will use for the rest of the course.

How a request flows through your endpoint

Every route you write follows the same path: request, router, service, response.

router.py
python
from fastapi import APIRouter

router = APIRouter(prefix="/bedtime-story", tags=["bedtime-story"])

@router.get("/health")
async def health_check():
    """Health check endpoint."""
    return {
        "status": "healthy",
        "service": "bedtime-story-generator"
    }

The @router.get decorator binds the function to GET /bedtime-story/health. The return dict is auto-serialized to JSON with a 200 status.

A few things happened there. The prefix on APIRouter adds /bedtime-story to every route in this file. The decorator @router.get("/health") is called a path operation: it says "this function handles GET at this path". And async def is the signal that FastAPI should run this on the event loop. You can use plain def too, and we will talk about when later in the course.

FastAPI wraps your return value in a JSONResponse automatically. It can serialize dicts, lists, Pydantic models, and common primitives. If you need to control headers or status, you can return a Response object directly, but most of the time returning a plain dict or Pydantic model is what you want.

Quiz: Quiz

Loading practice…