FastAPI Projektstruktur Best Practices

FastAPI Projektstruktur Best Practices

vg

FastAPI gehört zu den beliebtesten Python-Frameworks für den Aufbau moderner, leistungsstarker Web-APIs. Doch um eine skalierbare, wartbare und professionelle FastAPI-Anwendung zu entwickeln, reicht es nicht aus, nur die Grundfunktionen zu beherrschen. Eine durchdachte Projektstruktur, saubere Modularisierung und klare Best Practices sind entscheidend für den langfristigen Erfolg – besonders in Teams oder bei größeren Projekten.

In diesem Beitrag zeigen wir Ihnen, wie Sie Ihre FastAPI-Anwendung richtig strukturieren – mit Fokus auf:

  • Modularer Architektur
  • Fehlerbehandlung mit Custom Exception Handlers
  • Objektorientierter Programmierung (OOP)
  • Abhängigkeitsinjektion und Datenbankanbindung

Ob Sie gerade starten oder bestehende Projekte optimieren möchten – hier finden Sie einen praxisnahen Leitfaden für professionelle FastAPI-Entwicklung im Jahr 2025.

Warum Struktur wichtig ist

Eine gut organisierte Codebasis ist unerlässlich für:

  • Wartbarkeit: Eine klare Struktur erleichtert es Entwicklern, den Code zu verstehen und zu modifizieren.
  • Skalierbarkeit: Ein modularer Ansatz ermöglicht eine einfache Erweiterung, wenn neue Funktionen hinzugefügt werden.
  • Zusammenarbeit: Ein organisiertes Projekt erleichtert die Teamarbeit und reduziert Verwirrung.

Empfohlene Projektstruktur

Eine gut definierte Projektstruktur kann die Organisation Ihrer FastAPI-Anwendung erheblich verbessern. Nachfolgend finden Sie eine vorgeschlagene Verzeichnisstruktur:

/my_fastapi_app
|-- app/
| |-- __init__.py
| |-- main.py
| |-- api/
| | |-- __init__.py
| | |-- main.py
| |-- db/
| | |-- __init__.py
| | |-- connector.py
| | |-- db_instance.py
| |-- core/
| | |-- __init__.py
| | |-- exception_handlers.py
| | |-- logging.py
| | |-- models.py
| | |-- middleware/
| | | |-- __init__.py
| | | |-- jwt_auth_backend.py
| |-- routers/
| | |-- __init__.py
| | |-- user_router.py
|-- requirements.txt

Sie können auch separate Ordner für und für Pydantic-Modelle oder DB-Schemata erstellen, abhängig von Ihrem spezifischen Anwendungsfall. Daneben befindet sich auch der Ordner utils, in den Sie alle Dienstprogramme wie oder beliebige Dienstprogrammfunktionen integrieren können.modelsservicesconstants

Einrichten von FastAPI

Richten Sie in Ihrer Datei Ihre FastAPI-Anwendung ein und fügen Sie Middleware für die Authentifizierung hinzu:main.py

# app/main.py
from fastapi import FastAPI, HTTPException, Header, status
from starlette.middleware.authentication import AuthenticationMiddleware
from app.api.main import api_router
from app.core.middleware.jwt_auth_backend import JwtAuthBackend
from app.core.exception_handlers import (
http_exception_handler,
general_exception_handler,
on_auth_error,
)

app = FastAPI(
title="Project Name",
description="Project Description.",
version="1.0.0",
)

# Middleware setup
app.add_middleware(AuthenticationMiddleware, backend=JwtAuthBackend(), on_error=on_auth_error)

# Register custom exception handlers
app.add_exception_handler(HTTPException, http_exception_handler)
app.add_exception_handler(Exception, general_exception_handler)

# Include the API router
app.include_router(api_router)

api/main.py

Diese Datei registriert die Router für Ihre Anwendung.

from fastapi import APIRouter
from app.api.routers import items

api_router = APIRouter()

# Include the items router
api_router.include_router(items.router, prefix="/items", tags=["items"])

api/routers/items.py

Diese Datei enthält die CRUD-Operationen für eine hypothetische „items“-Ressource.

from fastapi import APIRouter, HTTPException, Depends, status, Request
from app.db.connector import PostgresConnector
from app.db.db_instance import get_postgres_connector
from app.core.logging import logger
from app.core.models import APIResponse

router = APIRouter()

# Simulated in-memory database for items
items_db = {}


@router.post(
"/",
status_code=status.HTTP_201_CREATED,
response_model=APIResponse,
)
async def create_item(item_id: int, item_data: dict):
"""Create a new item in the database."""
if item_id in items_db:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Item already exists.")

items_db[item_id] = item_data
return APIResponse(status="success", status_code=status.HTTP_201_CREATED, message="Item created successfully.")


@router.get(
"/{item_id}/",
status_code=status.HTTP_200_OK,
response_model=APIResponse,
)
async def get_item(item_id: int):
"""Retrieve an item by ID."""
item = items_db.get(item_id)
if not item:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Item not found.")

return APIResponse(status="success", status_code=status.HTTP_200_OK, message="Item retrieved successfully.", data=item)


@router.delete(
"/{item_id}/",
status_code=status.HTTP_204_NO_CONTENT,
)
async def delete_item(item_id: int):
"""Delete an item by ID."""
if item_id not in items_db:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Item not found.")

del items_db[item_id]
return APIResponse(status="success", status_code=status.HTTP_204_NO_CONTENT, message="Item deleted successfully.")

Database Connectivity

For efficient database connectivity, we create a class to handle connections and queries. Here’s an example of how to structure it:PostgresConnector

# app/db/connector.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

class PostgresConnector:
def __init__(self, env: str):
self.engine = create_engine(f"postgresql://user:password@localhost/{env}")
self.Session = sessionmaker(bind=self.engine)

def get_session(self):
return self.Session()

core/models.py

Diese Datei enthält freigegebene Antwortmodelle.

from pydantic import BaseModel

class APIResponse(BaseModel):
status: str
status_code: int
message: str
data: dict = None

Dependency Injection für Datenbankverbindungen

Mit der Abhängigkeitsinjektion von FastAPI können wir eine Funktion zum Abrufen des Datenbankkonnektors erstellen:

# app/db/db_instance.py
from fastapi import Header, Depends
from app.db.connector import PostgresConnector

def get_postgres_connector(
env: str = Header(..., alias="env", description="Environment Name"),
) -> PostgresConnector:
return PostgresConnector(env=env)

Fehlerbehandlung und benutzerdefinierte Ausnahmen

Die richtige Fehlerbehandlung verbessert die Benutzererfahrung und vereinfacht das Debuggen. Erstellen Sie benutzerdefinierte Ausnahmehandler in Ihrer :exception_handlers.py

# app/core/exception_handlers.py
from fastapi import Request, HTTPException
from fastapi.responses import JSONResponse

async def http_exception_handler(request: Request, exc: HTTPException):
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.detail},
)

async def general_exception_handler(request: Request, exc: Exception):
return JSONResponse(
status_code=500,
content={"detail": "An unexpected error occurred."},
)

async def on_auth_error(request: Request, exc: Exception):
return JSONResponse(
status_code=401,
content={"detail": "Authentication failed."},
)

Prüfung und Dokumentation

FastAPI bietet eine automatische Dokumentation über die Swagger-Benutzeroberfläche, die es einfach macht, Ihre API zu erkunden. Um sicherzustellen, dass die Anwendung ordnungsgemäß funktioniert, schreiben Sie Tests mit :pytest

# tests/test_user.py
import pytest
from fastapi.testclient import TestClient
from app.main import app

client = TestClient(app)

def test_put_simulation_status_waiting():
response = client.get("/itemsg/1/", headers={"env": "test"})
assert response.status_code == 200
assert response.json() == {"status": "success", "status_code": 200, "message": ""}

Fazit

Der Aufbau einer skalierbaren und wartbaren FastAPI-Anwendung beginnt mit einer klaren Struktur und einem konsequent umgesetzten Architekturansatz. Durch den Einsatz von modularem Design, objektorientierten Prinzipien und einer robusten Fehlerbehandlung schaffen Sie eine Codebasis, die nicht nur technisch überzeugt, sondern auch die Zusammenarbeit im Team erleichtert.

Nutzen Sie die in diesem Artikel gezeigten Best Practices für FastAPI, um Ihre Projekte zukunftssicher zu gestalten – ob für kleine APIs oder komplexe Microservices. Eine gut strukturierte FastAPI-Anwendung ist der Schlüssel zu hoher Produktivität, sauberem Code und effizienter Weiterentwicklung.

Bleiben Sie dabei flexibel, dokumentieren Sie konsequent – und denken Sie stets an Clean Code, Wiederverwendbarkeit und klare Schnittstellen.

Weiterer Beitrag: Open Source interne Tools, die du kennen musst

com

Newsletter Anmeldung

Bleiben Sie informiert! Wir informieren Sie über alle neuen Beiträge (max. 1 Mail pro Woche – versprochen)