API mit KI bauen: ein REST-Backend Schritt für Schritt

Praxisleitfaden, wie du eine API mit KI baust: Stack-Wahl, Schema und Migrationen, Auth, Validierung, Tests, OpenAPI-Docs, Deployment und typische Sicherheitsfehler.

Solviera Teknoloji 10 Min. Lesezeit

Eine API mit KI zu bauen, schaffst du an einem Nachmittag: Bitte einen Coding-Agenten wie Claude Code oder Codex um „eine REST-API für Aufgaben mit Nutzern“, und du bekommst Routen, eine Datenbank und einen laufenden Server. Ob diese API ihre ersten echten Nutzer übersteht, ist eine andere Frage. Nicht validierte Eingaben, Endpunkte, die fremde Daten herausgeben, und Migrationen, die niemand gelesen hat, sind die üblichen Probleme. In diesem Beitrag zeige ich, wie ich ein REST-Backend mit Agenten baue, von der Stack-Wahl bis zum Deployment, und wo du langsamer machen solltest.

Er gehört zur Reihe, die mit SaaS mit KI bauen begonnen hat. Dort geht es um das Produkt, hier um das Backend darunter, das eine Mobile-App, ein Frontend oder andere Dienste aufrufen. Wenn diese Arbeitsweise neu für dich ist, ist Vibe Coding lernen ein guter Einstieg.

1. Die API festlegen, bevor Code entsteht

Eine API ist ein Vertrag. Sobald eine Mobile-App dagegen ausgeliefert ist, wird das Umbenennen eines Feldes teuer. Bevor der Agent also Code schreibt, schreib Folgendes auf:

  • Ressourcen: die Substantive. Zum Beispiel users, projects, tasks, comments.
  • Endpunkte: GET /v1/projects, POST /v1/projects, GET /v1/projects/:id/tasks, PATCH /v1/tasks/:id und so weiter.
  • Wer was darf: „Mitglieder eines Projekts können seine Aufgaben lesen; nur der Eigentümer kann das Projekt löschen.“
  • Fehlerformat: eine Form für jeden Fehler, mit HTTP-Status, einem maschinenlesbaren Code und einer Meldung.
  • Paginierung: Cursor oder Seiten, Standard- und maximale Seitengröße.

Beschränk die erste Version auf die Endpunkte, die ein echter Client braucht. Eine Admin-API, Webhooks und Massenimport können warten.

2. Die Regeln in eine Spec-Datei schreiben

Agenten erinnern sich nicht an frühere Gespräche. Claude Code liest CLAUDE.md zu Beginn jeder Session; Codex und viele andere Agenten lesen AGENTS.md. Schreib deine Entscheidungen dort hinein:

# Tasks API

## Stack
- Node.js LTS, TypeScript, Fastify
- PostgreSQL, Prisma for schema and migrations
- Zod for request validation; OpenAPI generated from the same schemas
- Vitest; tests use app.inject() against a test database

## Rules
- All routes under /v1. JSON only.
- Every request body, query and param is validated with a schema.
- Errors: { "error": { "code": "...", "message": "..." } }, never a stack trace.
- Every query on tasks and projects checks project membership.
- Never return password hashes or tokens; use explicit response schemas.
- Database changes only through migration files.
- List endpoints: cursor pagination, default 20, max 100.
- Secrets come from environment variables; never in code or logs.
- Ask before adding a dependency.
- After every task: pnpm lint && pnpm test

## Out of scope (for now)
Admin API, file uploads, webhooks, GraphQL.

Jede Regel steht hier, weil Agenten es ohne sie falsch machen. „Explicit response schemas“ hält den Agenten davon ab, die ganze Nutzerzeile samt Passwort-Hash zurückzugeben. „Max 100“ verhindert, dass jemand eine Million Zeilen anfordert. Mehr zum Schreiben dieser Datei findest du in CLAUDE.md und AGENTS.md.

3. Einen langweiligen Stack wählen

Der Agent schreibt besseren Code auf einem Stack, den er tausendfach gesehen hat. Zwei sichere Optionen:

TypeScriptPython
FrameworkFastify (oder Express, Hono)FastAPI
ValidierungZod oder JSON SchemaPydantic
DatenbankzugriffPrisma oder DrizzleSQLAlchemy
MigrationenPrisma Migrate, Drizzle KitAlembic
OpenAPI@fastify/swaggerEingebaut
TestsVitest + app.inject()pytest + TestClient

Beide funktionieren. Nimm die Sprache, die du lesen kannst, denn du wirst viele Diffs lesen. In den Beispielen nutze ich TypeScript, Fastify, Prisma und PostgreSQL.

Lass Postgres lokal mit Docker laufen, damit der Agent nie eine gemeinsame Datenbank braucht:

docker run --name tasks-db -e POSTGRES_PASSWORD=dev -p 5432:5432 -d postgres:16
mkdir tasks-api && cd tasks-api && git init

4. Erst planen, dann eine Ressource nach der anderen

Mein erster Prompt fragt nach einem Plan, nicht nach Code:

Read CLAUDE.md. Don't write code yet.
Propose:
1. The Prisma schema (models, relations, indexes, unique constraints)
2. The full endpoint list with request and response shapes
3. How authorization works for each endpoint
4. 6–8 implementation steps, each ending with tests that pass
List open questions at the end.

Korrigiere den Plan, beantworte die Fragen, aktualisiere die Spec. Dann geht es Schritt für Schritt:

Implement step 2: the projects resource (list, create, get, update,
delete). Validate input with Zod, use explicit response schemas,
check membership on every query. Write tests for the happy path,
invalid input, and a second user who is not a member. Run the tests,
show me the result, then stop.

„Then stop“ ist Absicht: So kann ich den Diff lesen und committen, bevor der nächste Schritt beginnt. Wenn der Agent abdriftet, gehe ich einen Commit zurück, statt fünf Ressourcen zu entwirren.

5. Schema und Migrationen

Das Schema lässt sich später am schwersten ändern, also lies es sorgfältig:

  • Constraints in der Datenbank, nicht nur im Code. NOT NULL, eindeutige E-Mails, Fremdschlüssel mit bewusst gewähltem ON DELETE-Verhalten.
  • Indizes für die Abfragen, die du ausführst. Jeder Fremdschlüssel, nach dem du filterst, und jede Spalte, nach der ein Listen-Endpunkt sortiert.
  • Zeitstempel (createdAt, updatedAt) in jeder Tabelle; sie helfen beim Debuggen und bei der Cursor-Paginierung.
  • Geldbeträge als Ganzzahlen oder Dezimalwerte, nie als Gleitkommazahlen.

Jede Änderung läuft über eine Migration:

npx prisma migrate dev --name add_tasks   # create and apply locally
npx prisma migrate reset                  # rebuild the dev database from zero
npx prisma migrate deploy                 # apply pending migrations in production

Sobald echte Daten da sind, lies jede Migrationsdatei, die der Agent schreibt. Halte an und frag nach bei DROP COLUMN, DROP TABLE, Umbenennungen (Prisma kann daraus Löschen und Neuanlegen machen), UPDATE oder DELETE ohne WHERE und neuen NOT NULL-Spalten ohne Standardwert auf großen Tabellen.

6. Authentifizierung: Nimm, was es schon gibt

Lass den Agenten keine Passwortspeicherung und keine Token-Formate erfinden. Nimm einen gehosteten Auth-Anbieter oder eine bekannte Bibliothek, und beschränk die Aufgabe des Agenten aufs Einbinden:

  • Passwörter mit argon2 oder bcrypt über eine gepflegte Bibliothek hashen, nie im Klartext speichern oder loggen.
  • Sessions oder Tokens: Für einen Browser-Client auf derselben Site ist ein Session-Cookie mit HttpOnly, Secure und SameSite die einfachste sichere Wahl. Für Mobile- oder Drittanbieter-Clients kurzlebige Access-Tokens mit Refresh-Tokens.
  • Tokens richtig prüfen. Signatur, Ablauf, Aussteller und Zielgruppe; den Algorithmus none ablehnen. Lass dir vom Agenten genau zeigen, wo das passiert.
  • Rate-Limits für Login und Passwort-Reset, damit niemand Tausende Passwörter durchprobieren kann.

7. Autorisierung: der Bug, den Agenten am häufigsten schreiben

Authentifizierung beantwortet „Wer ist das?“. Autorisierung beantwortet „Darf diese Person diesen Datensatz anfassen?“. Von Agenten geschriebene APIs machen das Erste meist richtig und das Zweite falsch. Der Klassiker ist GET /v1/tasks/:id, das ein gültiges Token prüft und dann die Aufgabe per ID lädt. Jeder eingeloggte Nutzer kann jede Aufgabe lesen, indem er die Zahl ändert. OWASP führt genau das, Broken Object Level Authorization, auf Platz eins seiner API Security Top 10.

Die Lösung ist eine Gewohnheit, keine Bibliothek:

  • Jede Abfrage, die einen Datensatz per ID lädt, filtert zusätzlich danach, worauf der Aufrufer zugreifen darf: where: { id, project: { members: { some: { userId } } } }.
  • „Nicht gefunden“ und „nicht deins“ liefern dasselbe 404, damit niemand IDs ausprobieren kann.
  • Teste es mit zwei Nutzern bei jedem Endpunkt, der eine ID annimmt. Diese Tests sind die wertvollsten im ganzen Projekt.

Ein verwandter Fehler ist Mass Assignment: Der Agent reicht den Request-Body direkt an update() weiter, und ein Nutzer schickt "role": "admin" oder "ownerId": "...". Validierungsschemas, die nur die erlaubten Felder auflisten, verhindern das.

Frag den Agenten: „List every endpoint and the authorization check it performs. Mark any endpoint that loads a record by ID without filtering by the caller.“

8. Validierung und Fehler

Jede Eingabe, die die Grenze überschreitet, wird validiert: Body, Query-String, Pfadparameter und die Header, die du nutzt. Mit Zod und Fastify deklariert die Route ihre Schemas, und ungültige Requests werden mit 400 abgelehnt, bevor dein Code läuft.

  • Unbekannte Felder ablehnen, statt sie still zu ignorieren; so fallen Client-Bugs früh auf.
  • Größen begrenzen: Stringlängen, Arraylängen, Größe des Request-Bodys, Seitengröße.
  • Eine Fehlerform für alles und ein globaler Error-Handler, der die Details serverseitig loggt, dem Client aber nur code und message zurückgibt. Stacktraces und SQL-Fehler in Antworten sind eine Landkarte für Angreifer.
  • Nur parametrisierte Abfragen. Das ORM macht das standardmäßig; achte auf Helfer für rohes SQL mit String-Verkettung, etwa Prismas $queryRawUnsafe.

9. Tests, die zählen

Fastifys app.inject() schickt Requests an die App, ohne einen Port zu öffnen, deshalb sind API-Tests schnell. Du brauchst keine 100 % Abdeckung, aber diese hier:

  1. Der Happy Path jedes Endpunkts, mit Prüfung von Statuscode und Antwortform.
  2. Ungültige Eingaben liefern 400 in deinem Fehlerformat.
  3. Kein Token liefert 401; der Datensatz eines anderen liefert 404.
  4. Paginierung hält das Maximum ein.
  5. Migrationen laufen von null an auf einer leeren Datenbank durch.

Tests laufen gegen eine eigene Testdatenbank, die zwischen den Läufen zurückgesetzt wird. Lass die Testsuite nie in die Nähe von Produktionszugangsdaten.

Pass auf, wenn der Agent einen fehlschlagenden Test „repariert“, indem er die Assertion ändert. Taucht eine Testdatei in einem Diff auf, um den du nicht gebeten hast, frag nach dem Grund. KI-Code-Review hat dafür eine Checkliste.

10. OpenAPI-Docs aus denselben Schemas

Von Hand geschriebene Docs veralten. Erzeuge sie aus den Validierungsschemas, damit die Dokumentation genau beschreibt, was der Code akzeptiert. In Fastify baut @fastify/swagger ein OpenAPI-Dokument aus deinen Routen-Schemas, und @fastify/swagger-ui stellt es bereit; FastAPI kann das von Haus aus.

Add @fastify/swagger and @fastify/swagger-ui. Generate the OpenAPI
document from the existing route schemas, add descriptions and
examples, document the error format and auth. Serve the UI at /docs
only when NODE_ENV is not production.

Die OpenAPI-Datei nützt nicht nur als Doku: Frontend-Agenten können daraus einen typisierten Client erzeugen, und andere Tools finden darüber deine Endpunkte.

11. Deployment

Eine kleine API läuft problemlos als Container auf einer Plattform wie Fly.io, Railway oder Render oder auf jedem Server mit Docker. Eine Checkliste:

  • Ein Dockerfile mit Multi-Stage-Build und einem Nicht-Root-Benutzer. Lass es dir vom Agenten schreiben und lies es dann.
  • Migrationen als eigener Schritt (prisma migrate deploy), bevor die neue Version startet, nicht in jeder App-Instanz beim Hochfahren.
  • Umgebungsvariablen für Datenbank-URL, Secrets und erlaubte CORS-Origins, gesetzt in der Plattform, nicht im Image.
  • Ein Health-Endpunkt (/health), den die Plattform prüfen kann.
  • CORS auf deine echten Frontends beschränkt; nie * zusammen mit Credentials.
  • Nur HTTPS, Security-Header (zum Beispiel mit @fastify/helmet) und Request-Logging ohne Passwörter, Tokens oder personenbezogene Daten.
  • Backups für die Produktionsdatenbank eingeschaltet und mindestens einmal eine Wiederherstellung ausprobiert.
  • Fehler-Tracking wie Sentry, damit du von den 500ern erfährst, bevor deine Nutzer es dir sagen.

Wo die KI danebenliegt

  • Ganze Datenbankzeilen zurückgeben. Passwort-Hashes, interne Flags und die E-Mails anderer Nutzer im JSON. Explizite Antwortschemas beheben das.
  • APIs erfinden. Bibliotheksfunktionen, die es nicht gibt oder die sich vor Versionen geändert haben. Gib dem Agenten aktuelle Docs und kopiere Fehlermeldungen unverändert zurück.
  • Keine Paginierung. findMany() ohne Limit funktioniert, bis die Tabelle 200.000 Zeilen hat.
  • N+1-Abfragen. Eine Abfrage pro Element in einer Schleife. Lass den Agenten in der Entwicklung Abfragen loggen und such nach Wiederholungen.
  • Verschluckte Fehler. catch {}, das trotzdem 200 zurückgibt.
  • Secrets im Code. Ein fest eingetragenes JWT-Secret „nur vorübergehend“, das in der Produktion landet.
  • Ausufernder Umfang. „Ich habe auch noch einen Admin-Endpunkt hinzugefügt.“ Mach es rückgängig oder verschieb es in einen eigenen Branch.

Sicherheit: kurz, aber ernst

  • Halte .env in .gitignore; rotiere jeden Key, der jemals committet wurde.
  • Füge keine API-Keys in den Chat ein; der Agent braucht nur den Variablennamen.
  • Richte den Agenten auf eine lokale oder Staging-Datenbank, nie auf die Produktion.
  • Lies die Befehle, die der Agent ausführt, besonders Datenbankbefehle, rm, Force-Pushes und curl … | sh.
  • Führ ab und zu pnpm audit (oder das Gegenstück deines Paketmanagers) aus und gib die Ausgabe dem Agenten.
  • Setz Rate-Limits für öffentliche Endpunkte, nicht nur für den Login.

Mehr dazu, wie du Agenten auf deinem Rechner sicher betreibst, findest du in Sicherheit von KI-Coding-Agenten.

Wann ein menschlicher Entwickler dazukommt

Ein paar Stunden Review durch einen erfahrenen Backend-Entwickler zahlen sich aus:

  • Bevor sich echte Nutzer registrieren, für Authentifizierung und Autorisierung
  • Wenn die API personenbezogene Daten, Gesundheits- oder Zahlungsdaten speichert
  • Wenn ein Partner oder Enterprise-Kunde sich daran anbindet
  • Wenn die Performance einbricht: langsame Abfragen, fehlende Indizes, Verbindungslimits
  • Wenn du und der Agent denselben Bug dreimal nicht beheben konntet

Mach es ihnen leicht: die Spec-Datei, das OpenAPI-Dokument, den Migrationsordner und einen grünen Testlauf.

So mache ich das mit AgentVera

All das funktioniert in einem einzigen Terminal. Mit mehreren Agenten hilft AgentVera an diesen Stellen:

  • Parallele Arbeit in Worktrees. Im Workspace lasse ich einen Agenten an der API arbeiten und einen anderen am Frontend oder an den Tests, jeden in seinem eigenen Git-Worktree, damit sie sich nicht in die Dateien kommen. Die Methode steht in Git-Worktrees für parallele Agenten.
  • Endpunkte ohne zusätzliches Tool ausprobieren. Der API-Client findet die Endpunkte des Projekts in OpenAPI-Dateien und in Routen von Express, Fastify, Hono, Next.js, FastAPI, Django, NestJS und anderen. Ich schicke einen Request mit Parametern, Headern und Body, und wenn die Antwort ein Fehler ist, gebe ich Request und Response mit einem Klick an einen Agenten.
  • Sehen, was in der Datenbank gelandet ist. Der Datenbank-Manager öffnet das lokale Postgres, sodass ich die Zeilen prüfen kann, die der Agent angelegt hat, und DB Guard bewertet das Risiko jeder Migration, wenn der Agent seinen Turn beendet, und kann sie auf einer Schattendatenbank ausprobieren.
  • Container. Die Docker-Seite zeigt den Postgres-Container und seine Logs neben den Agenten.
  • Turns prüfen. Das Code-Review prüft jeden abgeschlossenen Turn, bevor ich merge.

Das beschleunigt vieles, aber was die API sicher macht, sind weiterhin die Spec, die Tests und dein eigenes Review.

Fazit

Um eine API mit KI zu bauen, leg zuerst den Vertrag fest, schreib die Regeln in CLAUDE.md oder AGENTS.md, wähl einen verbreiteten Stack und lass den Agenten eine Ressource nach der anderen mit Tests bauen. Validiere jede Eingabe, ändere die Datenbank nur über Migrationen, prüfe bei jedem Datensatz, wem er gehört, erzeuge OpenAPI aus denselben Schemas und führ Migrationen als eigenen Deploy-Schritt aus. Hol dir ein menschliches Review, bevor echte Nutzer kommen. Wenn du Backend-, Frontend- und Test-Agenten nebeneinander laufen lassen willst, lade AgentVera kostenlos herunter.

Häufige Fragen

Kann ich mit KI eine REST-API bauen, wenn ich kein Backend-Entwickler bin?

Für ein kleines Produkt kannst du mit einem Coding-Agenten eine funktionierende API bauen, solange du den Umfang klein hältst, die Regeln für den Agenten aufschreibst und jeden Endpunkt testest. Authentifizierung, Autorisierung und alles, was personenbezogene Daten oder Zahlungsdaten berührt, sollte vor dem Launch ein erfahrener Entwickler prüfen.

Welcher Stack eignet sich am besten, um eine API mit KI zu bauen?

Ein verbreiteter, den die Agenten oft gesehen haben: TypeScript mit Fastify oder Express oder Python mit FastAPI, dazu PostgreSQL und ein Migrationstool. Populäre Stacks bedeuten weniger erfundene Funktionen und mehr Hilfe, wenn du festhängst.

Was ist der häufigste Sicherheitsfehler in KI-geschriebenen APIs?

Fehlende Autorisierung auf Objektebene: Der Endpunkt prüft, ob der Nutzer eingeloggt ist, aber nicht, ob der Datensatz ihm gehört. Wer eine ID in der URL ändert, bekommt die Daten von jemand anderem. Teste das bei jedem Endpunkt, der eine ID annimmt, mit zwei Nutzern.

Sollte die KI meine Authentifizierung selbst schreiben?

Nein. Nimm für Passwörter, Sessions und Tokens eine bekannte Bibliothek oder einen gehosteten Auth-Anbieter. Lass den Agenten das einbinden und die Autorisierungsregeln schreiben, die zu deiner App gehören, und teste diese Regeln sorgfältig.

Wie bekomme ich OpenAPI-Docs für eine mit KI gebaute API?

Lass den Agenten sie aus denselben Schemas erzeugen, die auch die Requests validieren, zum Beispiel mit @fastify/swagger in Fastify oder den eingebauten Docs in FastAPI. Dann können die Docs nicht von dem abweichen, was der Code tatsächlich akzeptiert.

Hol deine Agenten an einen Tisch.

Lade AgentVera kostenlos herunter; deine installierten CLIs sind sofort startklar.

Weitere Beiträge