🌐 Detecting your location…

So erstellen Sie eine REST-API mit FastAPI

⏱️5 min read  ·  1,099 words

How to Build a REST API with FastAPI

FastAPI ist zur Standardwahl für neue Python-APIs geworden, und das aus gutem Grund: automatische OpenAPI-Dokumente, echte asynchrone Unterstützung und eine von Pydantic unterstützte Anforderungsvalidierung, die fehlerhafte Eingaben erkennt, bevor sie Ihre Geschäftslogik berühren. Dieses Tutorial erstellt eine funktionierende REST-API aus einem leeren Ordner zu einem datenbankgestützten CRUD-Dienst mit einer für die Authentifizierung geeigneten Struktur.

Inhaltsverzeichnis

Projekt-Setup

Erstellen Sie eine virtuelle Umgebung und installieren Sie die Kernpakete:

mkdir fastapi-todo && cd fastapi-todo
python3 -m venv venv
source venv/bin/activate

pip install fastapi uvicorn[standard] sqlmodel

uvicornist der ASGI-Server, der Ihre App tatsächlich ausführt;sqlmodelkombiniert SQLAlchemy und Pydantic für eine Datenbankschicht, die Modelle mit Ihren API-Schemas teilt.

Ihre erste Route

Erstellen Siemain.py:

from fastapi import FastAPI

app = FastAPI(title="Todo API")

@app.get("/")
def read_root():
    return {"message": "Todo API is running"}

Führen Sie es mit Hot Reload aus:

uvicorn main:app --reload

Besuchen Siehttp://127.0.0.1:8000und Sie sehen die JSON-Antwort. Besuchen Sie/docsund Sie verfügen bereits über eine interaktive Swagger-Benutzeroberfläche, die ausschließlich aus Ihren Funktionssignaturen generiert wird.

Anfrage- und Antwortmodelle mit Pydantic

Anstattrequest.json()manuell zu überprüfen Definieren Sie für fehlende Felder ein Modell und lassen Sie FastAPI für Sie validieren:

from pydantic import BaseModel

class TodoCreate(BaseModel):
    title: str
    done: bool = False

@app.post("/todos")
def create_todo(todo: TodoCreate):
    return {"title": todo.title, "done": todo.done}

Eine Anfrage senden fehlttitleund FastAPI gibt automatisch einen strukturierten 422-Fehler zurück – kein zusätzlicher Code erforderlich. Diese Validierungsebene ist der Hauptgrund dafür, dass Teams von Flask migrieren.

Hinzufügen einer Datenbank mit SQLModel

Mit SQLModel kann eine Klasse sowohl als Datenbanktabelle als auch als API-Schema dienen:

from sqlmodel import SQLModel, Field, create_engine, Session

class Todo(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    title: str
    done: bool = False

engine = create_engine("sqlite:///todos.db")

def init_db():
    SQLModel.metadata.create_all(engine)

def get_session():
    with Session(engine) as session:
        yield session

Rufen Sieinit_db()an beim Start mit dem Lifespan-Handler von FastAPI:

from contextlib import asynccontextmanager

@asynccontextmanager
async def lifespan(app: FastAPI):
    init_db()
    yield

app = FastAPI(title="Todo API", lifespan=lifespan)

Erstellen vollständiger CRUD-Endpunkte

Wenn die Modell- und Sitzungsabhängigkeit vorhanden ist, sind die vier CRUD-Operationen kurz und lesbar:

from fastapi import Depends, HTTPException
from sqlmodel import select

@app.post("/todos", response_model=Todo)
def create_todo(todo: Todo, session: Session = Depends(get_session)):
    session.add(todo)
    session.commit()
    session.refresh(todo)
    return todo

@app.get("/todos", response_model=list[Todo])
def list_todos(session: Session = Depends(get_session)):
    return session.exec(select(Todo)).all()

@app.get("/todos/{todo_id}", response_model=Todo)
def get_todo(todo_id: int, session: Session = Depends(get_session)):
    todo = session.get(Todo, todo_id)
    if not todo:
        raise HTTPException(status_code=404, detail="Todo not found")
    return todo

@app.put("/todos/{todo_id}", response_model=Todo)
def update_todo(todo_id: int, data: Todo, session: Session = Depends(get_session)):
    todo = session.get(Todo, todo_id)
    if not todo:
        raise HTTPException(status_code=404, detail="Todo not found")
    todo.title = data.title
    todo.done = data.done
    session.add(todo)
    session.commit()
    session.refresh(todo)
    return todo

@app.delete("/todos/{todo_id}")
def delete_todo(todo_id: int, session: Session = Depends(get_session)):
    todo = session.get(Todo, todo_id)
    if not todo:
        raise HTTPException(status_code=404, detail="Todo not found")
    session.delete(todo)
    session.commit()
    return {"ok": True}

HinweisDepends(get_session)– Das Abhängigkeitsinjektionssystem von FastAPI. Es läuftget_sessionÜbergibt für jede Anfrage das Ergebnis an Ihre Funktion und bereinigt es anschließend. Das gleiche Muster lässt sich auf Authentifizierung, Ratenbegrenzung und Paginierung skalieren, ohne dass die Boilerplate in jedem Handler wiederholt wird.

Fehlerbehandlung

HTTPExceptiondeckt die meisten Fälle ab, aber für domänenspezifische Fehler registrieren Sie einen benutzerdefinierten Ausnahmehandler, damit die Antworten in der gesamten API konsistent bleiben:

from fastapi.responses import JSONResponse
from fastapi import Request

class TodoLimitError(Exception):
    pass

@app.exception_handler(TodoLimitError)
def limit_handler(request: Request, exc: TodoLimitError):
    return JSONResponse(status_code=400, content={"error": "todo limit reached"})

Automatische Dokumente

Jede Route, die Sie geschrieben haben, ist bereits unter/docsdokumentiert (Swagger) und/redoc(ReDoc), generiert aus Ihren Pydantic-Modellen und Typhinweisen. Fügen Sie Beschreibungen mit einem Dokumentstring oderField(description=...)hinzu und sie werden automatisch im generierten Schema angezeigt – kein separates OpenAPI YAML, das manuell verwaltet werden muss.

Wird in der Produktion ausgeführt

Führen Sie für die Produktion Uvicorn hinter Gunicorn mit mehreren Workern aus oder verwenden Sie Uvicorns eigenen Multi-Worker-Modus:

gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000

Platzieren Sie es hinter Nginx oder einem verwalteten Load Balancer für die TLS-Beendigung und tauschen Sie SQLite gegen PostgreSQL aus, indem Siecreate_engineändern Verbindungszeichenfolge – Die API von SQLModel ändert sich nicht.

Wenn Sie diese API mit einem modernen Frontend kombinieren, ist unserNext.js 15 und PostgreSQL-Leitfadendeckt die Clientseite ab. Informationen zu asynchronen Grundlagen in JavaScript finden Sie unterunser async/await Deep Dive.

FAQ

Ist FastAPI schneller als Flask?
Die asynchrone Unterstützung und die Starlette-Basis von FastAPI machen es bei gleichzeitiger Last wesentlich schneller, insbesondere für E/A-gebundene Endpunkte wie Datenbankaufrufe oder externe API-Anfragen.

Benötige ich für jede Route eine asynchrone Definition?
Nein. FastAPI läuft synchrondefRouten in einem Thread-Pool automatisch. Verwenden Sieasync defwenn Sie asynchrone Bibliotheken (asynchrone DB-Treiber, httpx) aufrufen, um echte Parallelitätsvorteile zu erzielen.

Was ist der Unterschied zwischen Pydantic und SQLModel?
Pydantic validiert Datenformen für Anfragen und Antworten. SQLModel erweitert Pydantic-Modelle, sodass dieselbe Klasse auch einer Datenbanktabelle zugeordnet werden kann, wodurch doppelte Schemadefinitionen vermieden werden.

Wie füge ich eine Authentifizierung hinzu?
Verwenden SieOAuth2PasswordBearervon FastAPI mit Abhängigkeitsinjektion – einget_current_userDie Abhängigkeit validiert ein JWT und wird jeder Route hinzugefügt, die Schutz benötigt, sodass die Authentifizierungslogik an einem Ort bleibt.

Kann FastAPI mit WebSockets umgehen?
Ja, nativ. Definieren Sie eine Route mit@app.websocket("/ws")und einasync defHandler, derwebsocket.receive_text()erwartet in einer Schleife.

Bereit zum Bauen?

Klonen Sie den obigen Code in ein neues Projekt und führen Sieuvicorn main:app --reloadaus , und beginnen Sie mit der Erweiterung des Todo-Modells um Felder wie Fälligkeitstermine oder Priorität. Das Abhängigkeitsinjektionsmuster, das Sie für die Datenbanksitzung verwendet haben, ist dasselbe, das Sie später für Authentifizierung, Caching und Ratenbegrenzung verwenden werden.

TP
TechPulse-Team
Veröffentlicht am 1. August 2026


MD Rafikul Islam

Written by

MD Rafikul Islam is a software developer and the editor of TechPulse. He writes about developer tooling, hardware, and the practical decisions that come up in day-to-day engineering work — which laptop to buy, which framework to commit to, why a build broke at 2am. He tests the tools he writes about and says plainly when something is not worth the money. Corrections and corrections requests are welcome at rony.yf25@gmail.com.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা