REST i GraphQL API w Claude Code
Claude Code buduje niezawodne API REST i GraphQL, gdy kontrakt powstaje pierwszy: plik OpenAPI lub schemat GraphQL uzgodniony w trybie planowania, a potem implementacja po jednym zasobie, zaczynając od testów. Człowiek przegląda kontrakt. Lint specyfikacji, fuzzing zgodności ze schematem, test pokrycia uwierzytelniania i hook Stop dowodzą, że handlery się z nim zgadzają.
Partner potrzebuje dwunastu endpointów, OAuth2 client credentials, limitów zapytań i podpisanych webhooków w dwa tygodnie. Prosisz Claude Code o „API dla partnera” i dostajesz naraz 2000 linii: trzy różne kształty błędów, jedną trasę bez uwierzytelniania i plik OpenAPI, który opisuje to, o co prosiłeś, a nie to, co faktycznie trafiło do kodu. Ta strona jest dla programistów, którzy budują endpointy API w terminalu z Claude Code, oraz dla tech leadów, którzy chcą, żeby każda zmiana API w repozytorium przechodziła te same bramki bez przeglądu linijka po linijce.
Co zyskujesz, budując API w Claude Code tym sposobem
Dział zatytułowany „Co zyskujesz, budując API w Claude Code tym sposobem”- Pętlę kontrakt-najpierw: projekt w trybie planowania, zatwierdzenie specyfikacji, implementacja po jednym zasobie na iterację.
- Pięć promptów do skopiowania: projekt kontraktu, iteracja zasobu zaczynająca się od testów, test pokrycia uwierzytelniania, naprawa N+1 w GraphQL z asercją liczby zapytań oraz podpisane dostarczanie webhooków.
- Zestaw bramek, który dowodzi zgodności bez czytania każdego handlera: Spectral, Schemathesis, test pokrycia uwierzytelniania i hook
Stop. - Subagenta recenzenta kontraktów API w trybie tylko do odczytu, którego możesz zacommitować jeszcze dziś.
- Typowe awarie API pisanych przez agenta, każdą z procedurą naprawy.
Zapisz konwencje API przed pierwszym promptem
Dział zatytułowany „Zapisz konwencje API przed pierwszym promptem”Claude Code czyta CLAUDE.md na początku każdej sesji. Wpisz tam decyzje, które recenzent API sprawdza ręcznie, żeby agent nie musiał ich zgadywać, a każda iteracja stosowała tę samą odpowiedź. Gdzie umieścić plik, opisuje strona o ładowaniu plików pamięci Claude Code.
## API conventions (CLAUDE.md)- Contract: docs/openapi.yaml is the source of truth. Change it first, in its own commit.- Stack: Express + TypeScript, Zod for validation, Vitest + supertest for tests.- Every error response uses ErrorResponse from src/types/api.ts: { "error": "UPPER_SNAKE_CODE", "message": string, "requestId": string, "details"?: [...] }- Middleware order on every route: requestId -> auth -> rateLimit -> validate -> handler.- Every route under /api/v1/partner/ requires partnerAuth and requireScope(...). Exceptions: GET /health and POST /oauth/token. No others.- Lists use cursor pagination: { data, pagination: { nextCursor, hasMore } }. No offset.- Strings need maxLength, numbers min/max, arrays maxItems. No unbounded input.- Never log request bodies, tokens or Authorization headers.Trzy ostatnie reguły recenzent musiałby inaczej wyłapywać ręcznie, więc zapisz je wprost.
Jak zbudować w Claude Code API, któremu można ufać?
Dział zatytułowany „Jak zbudować w Claude Code API, któremu można ufać?”Kolejność ma większe znaczenie niż same prompty. Każdy krok daje coś, co możesz sprawdzić, zanim zacznie się następny.
-
Zaprojektuj kontrakt w trybie planowania.
Uruchom
claude --permission-mode planalbo wpisz/planw trwającej sesji. W trybie planowania Claude Code czyta kod i proponuje, ale niczego nie edytuje, więc o nazwy zasobów i kody statusu spierasz się, zanim powstanie jakikolwiek handler. To przypadek szczególny szerszej metody, którą opisuje strona o programowaniu sterowanym specyfikacją. -
Zlintuj kontrakt, a potem go zatwierdź.
Zapisz zatwierdzony projekt w
docs/openapi.yamli uruchom na nim Spectral w terminalu:Okno terminala npx @stoplight/spectral-cli lint docs/openapi.yaml --fail-severity warnSpectral potrzebuje zestawu reguł. Utwórz
.spectral.yamlzextends: ["spectral:oas"], żeby włączyć wbudowane reguły OpenAPI, i dopisz własne. Kontrakt to jedyny artefakt, który człowiek czyta w całości: nazwy zasobów, kody statusu, zakresy uprawnień i odpowiedzi na otwarte pytania Claude. Zacommituj go osobno, żeby każda późniejsza zmiana w nim była widoczna w przeglądzie. -
Implementuj po jednym zasobie na iterację, zaczynając od testów.
Wyjdź z trybu planowania skrótem Shift+Tab, który przełącza tryby uprawnień, i implementuj w trybie auto albo
acceptEdits. Od v2.1.283 (kanałlatest) tryb auto jest trybem startowym sesji interaktywnych w każdym planie i u każdego dostawcy, więc często trafiasz do niego bez wybierania. Wyjątkiem są sesje na modelach, których tryb auto nie obsługuje (np. domyślna sesja Microsoft Foundry), i sesje, w których plik ustawień zawieradisableAutoMode; jeśli startujesz w trybie Manual, wybierz auto alboacceptEditsskrótem Shift+Tab. Zaimplementuj produkty przed zamówieniami. Iteracja na tyle mała, że mieści się w jednej sesji, utrzymuje czysty kontekst i daje zielony punkt kontrolny, do którego wrócisz przez/rewind, jeśli kolejna iteracja się posypie. -
Sprawdź działające API ręcznie.
Uruchom serwer deweloperski i sprawdź iterację sam, w tej samej sesji. Linia zaczynająca się od
!uruchamia polecenie bezpośrednio w trybie powłoki, bez interpretowania i zatwierdzania przez Claude. Polecenie i jego wynik trafiają do kontekstu, więc Claude może zareagować na to, co pokazują. Nie wpisuj w te polecenia prawdziwych tokenów, bo wynik zostaje w transkrypcie.Okno terminala ! curl -s -w '\n%{http_code}\n' "http://localhost:3000/api/v1/products?minPrice=-1" \-H "Authorization: Bearer $API_TEST_TOKEN"Jedno wywołanie curl dowodzi jednej ścieżki. Krok 5 dowodzi reszty.
-
Sfuzzuj implementację na podstawie kontraktu.
Schemathesis generuje żądania z
docs/openapi.yaml, także niepoprawne, i sprawdza każdą odpowiedź względem zadeklarowanego schematu i kodów statusu:Okno terminala uvx schemathesis run docs/openapi.yaml --url http://localhost:3000 \--checks all -H "Authorization: Bearer $API_TEST_TOKEN" --max-failures 10Wklej błędy z powrotem do Claude z poleceniem „fix the implementation, not the spec, unless the spec is wrong; say which”. Każdy błąd to albo usterka handlera, albo decyzja kontraktowa, która wymaga człowieka. Testy kontraktowe między usługami i szerszą strategię testowania API opisuje strona o automatyzacji testów API.
-
Przeglądaj dowody, a nie każdy handler.
Uruchom
/code-reviewi/security-reviewna iteracji, a sprawdzenie kontraktu przekaż subagentowi recenzentowi z następnej sekcji. Ty czytasz diff kontraktu, listę testów i wynik bramek. Handler otwierasz tylko tam, gdzie wskazuje bramka albo recenzent.
Które bramki dowodzą, że API działa, bez czytania każdego handlera?
Dział zatytułowany „Które bramki dowodzą, że API działa, bez czytania każdego handlera?”Każda bramka łapie klasę błędów, którą człowiek przegapia, przeglądając pobieżnie 2000 linii. Pierwsze cztery uruchamiaj w CI przy każdym pull requeście; listą bramek zarządza tech lead i to on zatwierdza zmiany kontraktu.
| Bramka | Co łapie | Polecenie lub plik | Kiedy działa |
|---|---|---|---|
| Lint Spectral | Niespójne nazwy, brakujące odpowiedzi błędów, nieudokumentowane operacje | npx @stoplight/spectral-cli lint docs/openapi.yaml | Hook Stop, CI |
| Testy integracyjne | Złe kody statusu, zepsuta walidacja, macierz 401/403 | npm run test:api | Hook Stop, CI |
| Test pokrycia uwierzytelniania | Trasę zarejestrowaną bez partnerAuth albo bez sprawdzenia zakresu | tests/routes/auth-coverage.test.ts | CI |
| Schemathesis | Odpowiedzi niezgodne z kontraktem; błędy 500 przy nietypowym wejściu | uvx schemathesis run … --checks all | CI, na uruchomionym serwerze |
/security-review | Wstrzyknięcia, sekrety w logach, brak autoryzacji na ścieżce danych | W sesji | Przed pull requestem |
| Zatwierdzenie przez człowieka | Czy kontrakt opisuje właściwy produkt | Diff docs/openapi.yaml | Pull request |
Test pokrycia uwierzytelniania warto napisać pierwszego dnia, bo trasa bez uwierzytelniania przechodzi wszystkie pozostałe bramki. Niech wylicza trasy, które aplikacja faktycznie rejestruje, żeby nowa trasa była objęta testem bez niczyjej pamięci:
Ostatnie polecenie jest kluczowe: bramka, której nigdy nie widziałeś czerwonej, to bramka nieprzetestowana.
Niech Claude Code uruchamia bramki, zanim powie „gotowe”
Dział zatytułowany „Niech Claude Code uruchamia bramki, zanim powie „gotowe””Hook Stop uruchamia się, gdy Claude próbuje zakończyć turę. Jeśli bramki nie przechodzą, hook blokuje zakończenie i oddaje wynik agentowi, więc „gotowe” oznacza zielone bramki. Zapisz skrypt jako .claude/hooks/api-gates.sh i nadaj mu prawo wykonywania:
#!/usr/bin/env bash# .claude/hooks/api-gates.sh (Stop)set -uo pipefailcd "$CLAUDE_PROJECT_DIR" || exit 0retrying=$(jq -r '.stop_hook_active')[[ -z $(git status --porcelain -- docs/openapi.yaml src tests) ]] && exit 0
if out=$(npx @stoplight/spectral-cli lint docs/openapi.yaml --fail-severity warn 2>&1 \ && npm run --silent test:api 2>&1); then exit 0; fi
if [[ $retrying == "true" ]]; then jq -nc '{systemMessage: "API gates still fail after one retry. Stopping for a human."}' exit 0fijq -nc --arg r "API gates fail. Fix them before you finish. Last 40 lines:$(tail -n 40 <<<"$out")" '{decision: "block", reason: $r}'Hook uruchamia bramki tylko wtedy, gdy specyfikacja, src lub tests mają niezacommitowane zmiany, więc jeśli Claude zrobi commit w trakcie tury, hook przepuści ją bez żadnego sprawdzenia. Zabezpieczeniem dla zacommitowanej pracy jest CI.
Zarejestruj go w .claude/settings.json. Forma exec (command plus args) przekazuje ścieżkę skryptu jako jeden argument, więc zadziała także ścieżka projektu ze spacjami:
{ "hooks": { "Stop": [ { "hooks": [{ "type": "command", "command": "bash", "args": ["${CLAUDE_PROJECT_DIR}/.claude/hooks/api-gates.sh"], "timeout": 300 }] } ] }}Skrypt czyta pole stop_hook_active, które ma wartość true, gdy Claude już kontynuuje pracę z powodu hooka Stop, i poddaje się po jednej ponownej próbie. Claude Code sam ogranicza kontynuacje wymuszone hookiem Stop do ośmiu z rzędu, ale bramka, która zawodzi dwa razy, zwykle wymaga decyzji człowieka, a nie kolejnych prób. Wartość timeout jest w sekundach. Wzorzec „jedna ponowna próba, potem eskalacja do człowieka” i pozostałe zdarzenia hooków opisuje strona o hookach, które egzekwują twoje bramki.
Subagent recenzent, który sprawdza kontrakt, a nie styl
Dział zatytułowany „Subagent recenzent, który sprawdza kontrakt, a nie styl”Subagent przegląda kod we własnym oknie kontekstu i zwraca werdykt. Daj mu narzędzia tylko do odczytu, żeby nie mógł „naprawić” tego, co ma ocenić. Zapisz jako .claude/agents/api-contract-reviewer.md:
---name: api-contract-reviewerdescription: Checks that API handlers match docs/openapi.yaml and CLAUDE.md API conventions. Use after implementing or changing an endpoint.tools: Read, Grep, Glob---
You review API changes against docs/openapi.yaml and the API conventions in CLAUDE.md.You never edit files. For every changed route report, with file and line:- operations in the code that are missing from the spec, and the reverse- error responses that do not use ErrorResponse- middleware order that differs from CLAUDE.md- unbounded inputs (string without maxLength, array without maxItems)- list endpoints without cursor paginationEnd with VERDICT: PASS or VERDICT: FAIL and the count of findings.Traktuj jego werdykt jako twierdzenie do potwierdzenia, nie jako dowód: dowodem są bramki powyżej, a subagent znajduje to, czego one nie obejmują. Więcej wzorców znajdziesz na stronie o własnych subagentach.
Jak zbudować API GraphQL tą samą pętlą?
Dział zatytułowany „Jak zbudować API GraphQL tą samą pętlą?”Pętla jest ta sama, tylko zamiast docs/openapi.yaml masz plik schematu: napisz schema.graphql w trybie planowania, zatwierdź go i implementuj resolvery typ po typie. Błąd typowy dla GraphQL to zapytania N+1, które przechodzą każdy test funkcjonalny na małym zestawie danych. Zrób z liczby zapytań asercję w teście, żeby poprawka była udowodniona, a nie tylko zadeklarowana.
Schemathesis przyjmuje też schemat GraphQL: lokalny plik schema.graphql z --url albo sam adres endpointu, więc bramka fuzzingu przenosi się bez zmian. Do pracy z SQL świadomej schematu podłącz serwer MCP bazy danych, żeby Claude sprawdzał indeksy i plany zapytań na prawdziwym schemacie zamiast zgadywać.
Webhooki, limity zapytań i paginacja bez niespodzianek
Dział zatytułowany „Webhooki, limity zapytań i paginacja bez niespodzianek”Te trzy obszary psują się w API pisanych przez agenta na produkcji, a nie w testach, bo błąd ujawnia się dopiero przy ponowieniach, pod obciążeniem albo na dużych danych. Opisz w prompcie zachowanie w razie awarii i poproś o test tego zachowania.
Przy limitach zapytań i paginacji proś o konkretne sprawdzenia:
- Limity zapytań: test, który wysyła limit + 1 żądań i sprawdza odpowiedź
429z nagłówkiemRetry-After, a takżeX-RateLimit-Remainingw każdej odpowiedzi. Zapytaj, gdzie żyje licznik; licznik w pamięci procesu zeruje się przy każdym wdrożeniu i jest inny na każdej instancji. - Paginacja: test, który przechodzi przez 250 zasianych wierszy z włączonym filtrem i sprawdza brak duplikatów i brak luk. Błędy kursora ujawniają się dopiero przy remisach w kluczu sortowania, więc celowo zasiej remisy.
- Wydajność: test, który zasiewa 10 000 wierszy i mierzy liczbę zapytań oraz p95 opóźnienia endpointu listy dla każdego filtra. Zestaw 20 wierszy ukrywa brakujący indeks.
Co się psuje, gdy Claude Code pisze twoje API?
Dział zatytułowany „Co się psuje, gdy Claude Code pisze twoje API?”| Objaw | Przyczyna | Naprawa |
|---|---|---|
| Trzy różne kształty błędów w różnych endpointach | Brak jednego typu błędu w kontekście; każda iteracja wymyśliła własny | Dodaj regułę ErrorResponse do CLAUDE.md, a potem: „grep every res.status( and throw under src/routes/ and convert each to ErrorResponse; list what you changed.” Następnym razem wyłapie to Spectral, jeśli dodasz regułę wymagającą wspólnego schematu błędu. |
| Trasa trafia do kodu bez uwierzytelniania | Trasę dodano w późniejszej iteracji, a prompt nie powtórzył reguły | Test pokrycia uwierzytelniania; jeśli nie zawiódł, to nie wylicza prawdziwego routera. Najpierw napraw test, potem trasę. |
| Testy przechodzą, Schemathesis zwraca błędy 500 | Testy obejmują wejścia, o których pomyślał Claude; fuzzer wysyła te, o których nie pomyślał | Wklej niezaliczony przypadek do sesji i poproś o test regresyjny, który go odtwarza, zanim powstanie poprawka. |
| Claude zmienia specyfikację, żeby pasowała do błędnego handlera | Polecenie „make Schemathesis pass” da się spełnić, osłabiając kontrakt | Trzymaj zmiany docs/openapi.yaml w osobnych commitach i wymagaj dla tego pliku zatwierdzenia przez człowieka (wpis w CODEOWNERS). W każdym prompcie naprawczym pisz „fix the implementation, not the spec”. Ogólny wzorzec opisuje strona o ochronie wyroczni. |
| Claude osłabia albo usuwa niezaliczony test | Prompt nagradzał zieleń, a nie poprawność | Pisz „do not edit a test to make it pass” (prompt iteracji to robi) i porównuj liczbę testów przed i po w pull requeście. |
| Sesja dryfuje po kilku zasobach | Kontekst wypełniają wcześniejsze iteracje i wyniki testów | Jeden zasób na sesję; kolejny zacznij od /clear albo w nowej sesji. Długie przebiegi testów deleguj do subagenta, żeby wracały tylko błędy. |
| Walidacja odrzuca prawdziwe dane partnera | Granice zgadnięto, zamiast wziąć je z systemu źródłowego | Proś o granice jako otwarte pytania w prompcie kontraktu i odpowiedz na nie na podstawie przykładowych danych partnera przed zatwierdzeniem. |
Dokąd dalej po budowie API w Claude Code
Dział zatytułowany „Dokąd dalej po budowie API w Claude Code”Przewodnik międzynarzędziowy opisuje tę samą metodę spec-first dla Codex i Cursora, a do tego testy kontraktowe z Pact i wersjonowanie API. Sąsiednie strony o Claude Code obejmują warstwy pod API i wokół niego.
Planujesz funkcję, zanim powstanie kontrakt? Zacznij od planowania funkcji w Claude Code. Pracujesz w Codex? Zobacz tworzenie API w Codex.