Skip to course content
Free FastAPI backend course

FastAPI for AI Backend Development

Unit 02.00: A project layout that survives growth

One rule in the project layout does most of the work: the service layer must not import FastAPI.

Seven locations, one constraint

Routers hold HTTP concerns, services hold logic, and the two do not mix.

The code lists the layout with each directory's purpose.

LAYOUT = {
    "app/main.py":        "creates the FastAPI app, includes routers, nothing else",
    "app/routers/":       "one module per resource; HTTP concerns only",
    "app/services/":      "the actual logic; no FastAPI imports",
    "app/models.py":      "Pydantic request and response models",
    "app/settings.py":    "typed configuration from the environment",
    "app/dependencies.py": "shared dependencies",
    "tests/":             "mirrors app/, one file per module",
    "pyproject.toml":     "pinned dependencies",
}
for path, purpose in LAYOUT.items():
    print(f"{path:22} {purpose}")

print("""
The rule that does the work: `services/` must not import FastAPI. That keeps
the logic testable without HTTP, reusable from a worker or a script, and
portable if the framework ever changes.

`main.py` staying thin is what stops a project becoming one 2,000-line file.
""")

A service that imports no FastAPI can be called from a worker, a scheduled job, a migration or a test - without a request object, a test client or an event loop. That is what makes the logic reusable rather than merely tidy.

main.py staying thin is the other half. It creates the app and includes routers, and nothing else, which is what stops a project becoming one very long file.

The mistake this prevents

The mistake is putting logic in the router because it is only three lines. It is three lines until it is thirty, and by then it can only be reached through HTTP - so testing it needs a client and reusing it needs a request.

Takeaway

Routers handle HTTP, services hold the logic, and services import no FastAPI. That single constraint keeps the logic testable and reusable.