Wzorce rozwoju serverless
Twoja Lambda przetwarzająca obrazy odpala się dwa razy na ten sam upload do S3, więc połowa miniatur zostaje zapisana, usunięta i zapisana ponownie — a CloudWatch to ściana nieustrukturyzowanych console.log, których nie da się powiązać z żadnym żądaniem. W międzyczasie p99 skacze co rano do 4 sekund przez cold starty, a „poprawka”, którą ktoś wdrożył (provisioned concurrency na każdej funkcji), podwoiła rachunek. Serverless usuwa serwery, a nie problemy systemów rozproszonych: ponowienia, idempotencja, cold starty i limity poszczególnych platform to teraz Twój kod.
Ten przepis pokazuje, jak sterować Cursor, Claude Code i Codex, by generowały kod serverless, który przetrwa te problemy — a nie demo na szczęśliwej ścieżce, które psuje się przy pierwszym ponownym dostarczeniu wiadomości przez SQS.
Co z tego wyniesiesz
Dział zatytułowany „Co z tego wyniesiesz”- Gotowy prompt, który tworzy idempotentny handler AWS Lambda (deduplikacja przy ponowieniach) ze strukturalnym logowaniem do CloudWatch
- Wzorzec API gateway na Cloudflare Workers z prawdziwym
wrangler.tomloraz to, jak serwer MCP Cloudflare podgląda KV/R2/D1 bez wychodzenia z edytora - Workflow triage cold startów, który mówi, kiedy provisioned concurrency naprawdę jest warta swojej ceny
- Podział na trzy narzędzia: kiedy używać agenta w Cursor, headless runs w Claude Code i Codex Cloud do PR-ów wdrożeniowych
- Tryby awarii, które gryzą na produkcji — zduplikowane dostarczenia z SQS, hot partitions w DynamoDB, limity CPU w Workers — oraz prompty, które im zapobiegają
Workflow
Dział zatytułowany „Workflow”Krok 1: Zbuduj szkielet usługi (gdzie trzy narzędzia się różnią)
Dział zatytułowany „Krok 1: Zbuduj szkielet usługi (gdzie trzy narzędzia się różnią)”Etap budowania szkieletu to moment, w którym ergonomia narzędzi rozjeżdża się najbardziej. Cursor edytuje pliki wizualnie w Twoim repozytorium; Claude Code uruchamia CLI frameworka z terminala i da się skryptować w CI; Codex potrafi rozdzielić to samo zadanie do worktree w chmurze i otworzyć PR wdrożeniowy. Wybieraj według tego, gdzie żyje praca, a nie według możliwości — wszystkie trzy sterują tymi samymi CLI: AWS SAM / Serverless Framework / Wrangler.
Otwórz tryb Agent (Cmd/Ctrl + I) w pustym repozytorium i daj mu jedną konkretną usługę do zbudowania:
Set up a Serverless Framework v4 service in TypeScript targeting AWS
eu-central-1. One HTTP Lambda behind API Gateway (GET /health), one S3-triggered Lambda for image processing, and a DynamoDB tablemedia(PKid). Use esbuild bundling, Node 22 runtime, and putstage/regioninserverless.ymlprovider vars. Add adevandprodstage.
Agent pisze serverless.yml, zaślepki handlerów i package.json. Przejrzyj diff w pasku bocznym przed zaakceptowaniem — Cursor zapisuje checkpoint przy każdej edycji, więc możesz cofnąć zły plik bez utraty reszty.
Claude Code uruchamia CLI frameworka za Ciebie i jest właściwym wyborem, gdy chcesz mieć budowanie szkieletu odtwarzalne w skrypcie lub kroku CI. Daj mu tę samą konkretną specyfikację jako prompt pozycyjny:
claude "Set up a Serverless Framework v4 service in TypeScript targeting AWS eu-central-1: one HTTP Lambda behind API Gateway (GET /health), one S3-triggered image-processing Lambda, and a DynamoDB table 'media' (PK id). Use esbuild bundling, Node 22 runtime, and stage/region provider vars in serverless.yml."Agent edytuje pliki i sam uruchamia npx serverless; nie wyświetla kreatora wyboru dostawcy — dostawcę podajesz w prompcie. Dodaj --permission-mode acceptEdits, gdy zaufasz planowi, by przestał pytać przed każdym zapisem.
Codex obejmuje CLI, IDE i Cloud. Do jednorazowego lokalnego szkieletu uruchom go nieinteraktywnie i pozwól mu edytować workspace:
codex exec --full-auto "Scaffold a Serverless Framework v4 TypeScript service for AWS eu-central-1 with an HTTP /health Lambda, an S3-triggered image Lambda, a DynamoDB 'media' table, esbuild, Node 22, and stage/region provider vars."--full-auto ustawia --ask-for-approval on-request i --sandbox workspace-write, więc Codex może zapisywać pliki, ale wciąż zatrzymuje się przed czymkolwiek ryzykownym. Gdy chcesz szkielet oraz PR do przeglądu, wypchnij go do worktree w chmurze poleceniem codex cloud exec "<same prompt>, then open a PR" — Codex działa w izolowanym środowisku i oddaje gotową gałąź.
Krok 2: Uczyń handler idempotentnym (część, którą dema pomijają)
Dział zatytułowany „Krok 2: Uczyń handler idempotentnym (część, którą dema pomijają)”S3, SQS i EventBridge dostarczają co najmniej raz. Naiwny handler przetwarza ten sam obiekt ponownie przy retry. Rozwiązaniem jest klucz deduplikacji — dla S3 to eTag obiektu — sprawdzany zapisem warunkowym przed wykonaniem pracy. To najcenniejsza rzecz, jaką możesz umieścić w prompcie, więc powiedz to wprost:
Ten prompt tworzy coś zbliżonego do tego — zwróć uwagę na wczesny return przy duplikacie i strukturalny log, bo to właśnie czyni kod możliwym do debugowania na produkcji:
// handler.ts — the AI-generated shape worth reviewing forimport { S3Event } from 'aws-lambda';import { DynamoDBClient, PutItemCommand } from '@aws-sdk/client-dynamodb';
const ddb = new DynamoDBClient({});
export const handler = async (event: S3Event) => { const start = Date.now(); for (const rec of event.Records) { const { bucket, object } = rec.s3; const pk = `${bucket.name}/${object.key}#${object.eTag}`; const log = { requestId: rec.responseElements['x-amz-request-id'], bucket: bucket.name, key: object.key, eTag: object.eTag }; try { await ddb.send(new PutItemCommand({ TableName: process.env.DEDUPE_TABLE!, Item: { pk: { S: pk } }, ConditionExpression: 'attribute_not_exists(pk)', })); } catch (err: any) { if (err.name === 'ConditionalCheckFailedException') { console.log(JSON.stringify({ ...log, status: 'duplicate-skipped' })); continue; // already processed — S3 redelivery } throw err; } // ... resize with sharp, write derived/ objects ... console.log(JSON.stringify({ ...log, status: 'ok', durationMs: Date.now() - start })); }};To, co trzeba zweryfikować w wyniku AI: że zapis deduplikacyjny dzieje się przed efektami ubocznymi oraz że blok catch ponownie rzuca wyjątek (żeby DLQ faktycznie łapał awarie), zamiast go połykać.
Krok 3: API gateway na Cloudflare Workers
Dział zatytułowany „Krok 3: API gateway na Cloudflare Workers”Na Workers ograniczenia są inne — brak środowiska Node, budżet czasu CPU na żądanie i bindings zamiast klientów SDK. Poproś o gateway i konfigurację razem, żeby bindings w wrangler.toml pasowały do kodu:
# wrangler.toml — the AI should produce bindings that match the Workername = "api-gateway"main = "src/index.ts"compatibility_date = "2026-06-01"
[vars]ORIGIN = "https://origin.internal.example.com"
[[kv_namespaces]]binding = "TOKENS"id = "<your-kv-id>"
[[durable_objects.bindings]]name = "RATE_LIMITER"class_name = "RateLimiter"
[[migrations]]tag = "v1"new_sqlite_classes = ["RateLimiter"]Krok 4: Podgląd działającej infrastruktury serwerem MCP Cloudflare
Dział zatytułowany „Krok 4: Podgląd działającej infrastruktury serwerem MCP Cloudflare”Wygenerowanie Workera to połowa roboty; błędy żyją w wartościach bindings — źle wpisane id namespace’u KV, nieaktualny wiersz w D1. Bez MCP przełączasz się alt-tabem między dashboardem a edytorem. Z zarządzanymi zdalnymi serwerami MCP Cloudflare AI czyta rzeczywisty stan Twojego konta oraz dokumentację w tej samej rozmowie. Konfiguracja jest identyczna we wszystkich trzech narzędziach — wskaż im zdalne endpointy (pełny katalog serwerów i przepływ OAuth w przewodniku Cloudflare MCP):
{ "mcpServers": { "cloudflare-bindings": { "command": "npx", "args": ["-y", "mcp-remote", "https://bindings.mcp.cloudflare.com/mcp"] }, "cloudflare-observability": { "command": "npx", "args": ["-y", "mcp-remote", "https://observability.mcp.cloudflare.com/mcp"] } }}Przed MCP debugowanie błędu nieaktualnego cache oznaczało kopiowanie id namespace’ów między czterema kartami przeglądarki. Po: „Read the TOKENS KV namespace bound to the api-gateway Worker and list the keys written in the last hour” i AI odpowiada na podstawie Twojego działającego konta. Do wdrożeń i edycji bindings z CLI lżejszą alternatywą jest skill Cloudflare wrangler — zainstaluj go poleceniem npx skills add cloudflare/skills/wrangler (z repozytorium cloudflare/skills, wymienionego na skills.sh). Skill lepiej pasuje, gdy chcesz tylko, by agent znał polecenia i konwencje wrangler; serwer MCP wygrywa, gdy potrzebujesz, by czytał stan na żywo.