OpenAPI + Zod mit Claude Code: API-First Development 2026

API-First bedeutet: Schema zuerst, Code danach. Mit OpenAPI und Zod generiert Claude Code typsichere API-Clients, Validierungsschemas und vollständige Dokumentation — direkt aus einer einzigen Source of Truth.

OpenAPI Schema mit Claude Code designen

SchemaOpenAPI 3.1 YAML/JSON

# Prompt: "Erstelle OpenAPI 3.1 Schema fuer eine Project-Management-API" # openapi.yaml — Claude Code generiert vollstaendiges Schema: openapi: "3.1.0" info: title: Project Management API version: "1.0.0" components: schemas: Project: type: object required: [id, name, orgId, createdAt] properties: id: type: string format: cuid name: type: string minLength: 1 maxLength: 200 orgId: type: string status: type: string enum: [active, archived, deleted] default: active tags: type: array items: type: string createdAt: type: string format: date-time CreateProjectDto: type: object required: [name, orgId] properties: name: type: string minLength: 1 orgId: type: string securitySchemes: bearerAuth: type: http scheme: bearer paths: /projects: get: summary: List projects security: [{bearerAuth: []}] parameters: - name: orgId in: query required: true schema: {type: string} - name: page in: query schema: {type: integer, default: 1} responses: "200": content: application/json: schema: type: object properties: data: type: array items: {$ref: "#/components/schemas/Project"} total: {type: integer} "401": description: Unauthorized

Code-Generierung mit openapi-typescript

CodegenTypeScript-Typen aus OpenAPI

# Typen generieren (einmalig oder im CI) npx openapi-typescript openapi.yaml -o src/types/api.ts # Generierte Typen nutzen mit openapi-fetch: import createClient from "openapi-fetch"; import type { paths } from "./types/api"; const client = createClient<paths>({ baseUrl: "/api" }); // Vollstaendig typsicher — keine manuellen Typen! const { data, error } = await client.GET("/projects", { params: { query: { orgId: "org-123", page: 1 }, }, }); // data ist typed als { data: Project[], total: number } // error ist typed als 401-Response-Schema const { data: newProject } = await client.POST("/projects", { body: { name: "Neues Projekt", orgId: "org-123" }, // body ist typed als CreateProjectDto }); # package.json Script fuer automatische Regenerierung: # "generate:api": "openapi-typescript openapi.yaml -o src/types/api.ts" # In CI: npm run generate:api && git diff --exit-code
Codegen-Tipp: "Generiere TypeScript-Typen aus meinem OpenAPI-Schema und zeige mir wie ich openapi-fetch typsicher nutze." Claude Code schreibt das gesamte Client-Setup mit korrekten Generic-Typen.

Zod aus OpenAPI generieren

ValidationServer-seitige Validation mit Zod

# openapi-zod-client: Zod-Schemas aus OpenAPI npx openapi-zod-client openapi.yaml -o src/schemas/api.ts # Oder: manuell mit zod-to-openapi (umgekehrter Weg) import { extendZodWithOpenApi, OpenApiGeneratorV31 } from "@asteasolutions/zod-to-openapi"; import { z } from "zod"; extendZodWithOpenApi(z); // Zod-Schema mit OpenAPI-Metadaten const ProjectSchema = z.object({ id: z.string().cuid().openapi({ example: "clxxxxxxx" }), name: z.string().min(1).max(200).openapi({ example: "Mein Projekt" }), orgId: z.string(), status: z.enum(["active", "archived"]).default("active"), }).openapi("Project"); // OpenAPI-Dokument aus Zod generieren: const generator = new OpenApiGeneratorV31([registry]); const document = generator.generateDocument({ openapi: "3.1.0", info: { title: "API", version: "1.0.0" }, }); // Vorteil: Zod = Source of Truth → OpenAPI wird generiert, nicht umgekehrt

API-Client mit React Query

ClientTypsichere Queries aus OpenAPI

# Prompt: "Erstelle React Query Hooks aus meinem OpenAPI-Client" // hooks/useProjects.ts — generierter + manueller Layer import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { client } from "../lib/api-client"; export function useProjects(orgId: string) { return useQuery({ queryKey: ["projects", orgId], queryFn: async () => { const { data, error } = await client.GET("/projects", { params: { query: { orgId } }, }); if (error) throw new Error("Failed to fetch projects"); return data; }, }); } export function useCreateProject() { const qc = useQueryClient(); return useMutation({ mutationFn: async (body: CreateProjectDto) => { const { data, error } = await client.POST("/projects", { body }); if (error) throw new Error("Failed to create project"); return data; }, onSuccess: (_, { orgId }) => { qc.invalidateQueries({ queryKey: ["projects", orgId] }); }, }); }

API-Design im Kurs

Im Claude Code Mastery Kurs: vollstaendiges API-First-Modul mit OpenAPI Schema-Design, Code-Generierung, Zod-Validation und React Query Integration — inkl. CI-Pipeline fuer automatische Schema-Synchronisation.

14 Tage kostenlos testen →