Claude Code से Serverless Functions बनाना: Lambda और Workers
Claude Code से सुरक्षित serverless functions बनाएं: platform choice, secrets, idempotency, retries, tests और deploy checklist.
Serverless functions ऐसे छोटे code blocks हैं जो हर event या HTTP request पर चलते हैं, बिना यह कि आपको हमेशा चलने वाला server manage करना पड़े। Webhook, छोटी JSON API, image/CSV processing entry point और edge redirect जैसे कामों में यह बहुत उपयोगी है। लेकिन timeout, retry, secrets, permissions, logs और cost फिर भी production decisions हैं।
Claude Code इस workflow में अच्छा काम करता है क्योंकि handler, event fixture, tests, deploy notes और review checklist एक ही context में बन सकते हैं। Safe pattern यह नहीं है कि Claude Code सीधे deploy करे। Safe pattern है: requirements लिखें, runtime/platform चुनें, event local reproduce करें, config और secrets अलग रखें, idempotency design करें, failure tests चलाएं, फिर exposure और cost human review से pass करें।
Official docs साथ रखें: AWS Lambda Documentation, Lambda with Node.js, Cloudflare Workers development and testing और Workers get started guide. Related internal guides: AWS Lambda guide, Cloudflare Workers guide, API development guide, और secrets management guide.
Use Case पहले तय करें
Serverless तब अच्छा है जब काम छोटा हो, event-shaped हो, और retry होने पर data खराब न करे।
| Use case | क्यों fit है | Claude Code क्या draft करे | Human review |
|---|---|---|---|
| Payment या form webhook | एक request एक event बनता है | signature check, fixture, failure response | secrets, duplicate events, replay |
| Image resize या CSV import entry | heavy work storage/queue में जा सकता है | validation, job ID, JSON logs | file size, timeout, cleanup |
| Internal JSON API | छोटे endpoint के लिए persistent server नहीं चाहिए | handler, tests, route | auth, CORS, exposure, rate limit |
| Edge redirect/cache | user के पास response मिलता है | Worker route, cache headers, rollout notes | cache purge, personal data, SEO |
flowchart LR
A[Requirements prompt] --> B[Lambda या Workers चुनें]
B --> C[Event local reproduce]
C --> D[Env और secrets अलग]
D --> E[Idempotency और retry]
E --> F[Tests]
F --> G[Dev deploy]
G --> H[Logs और cleanup]
Claude Code Prompt
Feature name alone काफी नहीं है। Input, output, failure behavior और human confirmation points साफ लिखें।
Node.js में minimal serverless function बनाएं।
Goal:
- POST /orders handle करे और accepted order response return करे
- node local-test.mjs से local run हो
- AWS Lambda HTTP API v2 events assume करे
Requirements:
- index.mjs, events/create-order.json, local-test.mjs, index.test.mjs explain करें
- idempotency-key header missing हो तो 400
- same idempotency-key repeat हो तो same response
- invalid JSON, invalid input, unsupported route अलग करें
- JSON logs, लेकिन secrets या personal data log न करें
- deployment checklist दें
Constraints:
- external npm package नहीं
- production idempotency DynamoDB, KV या durable store में होगी
- IAM, public URL और billable resources human confirmation मांगें
Lambda या Workers
AWS events, IAM, S3, DynamoDB, SQS या EventBridge चाहिए तो AWS Lambda बेहतर है। Edge HTTP, redirect, lightweight API, cache, KV/D1/R2 flow चाहिए तो Cloudflare Workers अच्छा है। Vercel Functions Next.js app के साथ useful है, लेकिन यहां examples Lambda और Workers पर रखे गए हैं।
| Criteria | AWS Lambda | Cloudflare Workers |
|---|---|---|
| Best fit | AWS integrations, business APIs, async jobs | Edge HTTP, routing, cache, lightweight APIs |
| Local workflow | Node.js, SAM, AWS CLI | Wrangler |
| Permissions | IAM role/policy | Bindings, secrets, account permissions |
| Risk | broad IAM, VPC/NAT cost, log volume | binding drift, runtime limits, KV consistency |
Runnable Lambda Handler
// index.mjs
import crypto from "node:crypto";
const localIdempotencyStore = new Map();
function json(statusCode, body) {
return {
statusCode,
headers: { "content-type": "application/json" },
body: JSON.stringify(body),
};
}
function readHeader(headers = {}, name) {
const target = name.toLowerCase();
const found = Object.entries(headers).find(([key]) => key.toLowerCase() === target);
return found?.[1];
}
function parseBody(event) {
if (!event.body) return {};
const raw = event.isBase64Encoded
? Buffer.from(event.body, "base64").toString("utf8")
: event.body;
return JSON.parse(raw);
}
export async function handler(event = {}, context = {}) {
const method = event.requestContext?.http?.method ?? event.httpMethod ?? "GET";
const path = event.rawPath ?? event.path ?? "/";
const requestId = context.awsRequestId ?? crypto.randomUUID();
console.log(JSON.stringify({ level: "info", message: "request.start", requestId, method, path }));
if (method !== "POST" || path !== "/orders") {
return json(404, { error: "not_found" });
}
const idempotencyKey = readHeader(event.headers, "idempotency-key");
if (!idempotencyKey) {
return json(400, { error: "idempotency_key_required" });
}
if (localIdempotencyStore.has(idempotencyKey)) {
return json(200, { ...localIdempotencyStore.get(idempotencyKey), replay: true });
}
let body;
try {
body = parseBody(event);
} catch {
return json(400, { error: "invalid_json" });
}
if (!Number.isFinite(body.amount) || body.amount <= 0 || typeof body.currency !== "string") {
return json(400, { error: "invalid_order" });
}
const accepted = {
orderId: crypto.randomUUID(),
status: "accepted",
amount: body.amount,
currency: body.currency,
};
localIdempotencyStore.set(idempotencyKey, accepted);
console.log(JSON.stringify({ level: "info", message: "order.accepted", requestId, orderId: accepted.orderId }));
return json(202, accepted);
}
{
"version": "2.0",
"routeKey": "POST /orders",
"rawPath": "/orders",
"headers": {
"content-type": "application/json",
"idempotency-key": "demo-key-001"
},
"requestContext": {
"http": {
"method": "POST",
"path": "/orders"
}
},
"body": "{\"amount\":3200,\"currency\":\"INR\"}",
"isBase64Encoded": false
}
// local-test.mjs
import { readFile } from "node:fs/promises";
import { handler } from "./index.mjs";
const eventPath = process.argv[2] ?? "events/create-order.json";
const event = JSON.parse(await readFile(eventPath, "utf8"));
const first = await handler(event, { awsRequestId: "local-001" });
const second = await handler(event, { awsRequestId: "local-002" });
console.log("first:", first.statusCode, first.body);
console.log("second:", second.statusCode, second.body);
node local-test.mjs events/create-order.json
यह Map केवल local demo है। Production में idempotency DynamoDB conditional write, database unique constraint, Cloudflare KV/D1 या किसी durable store में रखें।
Tests
// index.test.mjs
import crypto from "node:crypto";
import test from "node:test";
import assert from "node:assert/strict";
import { handler } from "./index.mjs";
function event(overrides = {}) {
return {
rawPath: "/orders",
headers: { "idempotency-key": crypto.randomUUID() },
requestContext: { http: { method: "POST" } },
body: JSON.stringify({ amount: 1200, currency: "INR" }),
isBase64Encoded: false,
...overrides,
};
}
test("requires idempotency-key", async () => {
const result = await handler(event({ headers: {} }), {});
assert.equal(result.statusCode, 400);
});
test("accepts a valid order", async () => {
const result = await handler(event(), {});
assert.equal(result.statusCode, 202);
assert.equal(JSON.parse(result.body).status, "accepted");
});
test("rejects invalid JSON", async () => {
const result = await handler(event({ body: "not-json" }), {});
assert.equal(result.statusCode, 400);
});
node --test index.test.mjs
Workers Version
// src/worker.js
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (request.method !== "POST" || url.pathname !== "/orders") {
return Response.json({ error: "not_found" }, { status: 404 });
}
if (request.headers.get("x-webhook-secret") !== env.WEBHOOK_SECRET) {
return Response.json({ error: "unauthorized" }, { status: 401 });
}
const idempotencyKey = request.headers.get("idempotency-key");
if (!idempotencyKey) {
return Response.json({ error: "idempotency_key_required" }, { status: 400 });
}
const existing = await env.IDEMPOTENCY_KV.get(idempotencyKey, "json");
if (existing) {
return Response.json({ ...existing, replay: true });
}
const body = await request.json();
if (!Number.isFinite(body.amount) || typeof body.currency !== "string") {
return Response.json({ error: "invalid_order" }, { status: 400 });
}
const accepted = {
orderId: crypto.randomUUID(),
status: "accepted",
amount: body.amount,
currency: body.currency,
};
await env.IDEMPOTENCY_KV.put(idempotencyKey, JSON.stringify(accepted), {
expirationTtl: 86400,
});
return Response.json(accepted, { status: 202 });
},
};
npm create cloudflare@latest serverless-orders-worker
cd serverless-orders-worker
npx wrangler kv namespace create IDEMPOTENCY_KV
npx wrangler secret put WEBHOOK_SECRET
npx wrangler dev
Pitfalls और Checklist
पहला pitfall है exactly-once execution मान लेना। Webhooks, queues, async events और browsers retry कर सकते हैं। दूसरा pitfall है secrets को logs या examples में leak करना। तीसरा pitfall है Resource: "*" जैसी broad permission accept करना। चौथा pitfall है public endpoint बना देना, लेकिन auth, CORS, rate limit, log retention और cleanup date तय न करना।
| Check | क्या confirm करें |
|---|---|
| Requirements | input, output, owner और failure responses documented हैं |
| Runtime | Lambda Node.js runtime या Workers compatibility_date explicit है |
| Local | fixture और node --test pass हैं |
| Env/secrets | config और secrets अलग हैं |
| Idempotency | retry duplicate charge या duplicate create नहीं करता |
| Timeout/retry | slow work queue या durable job में जाता है |
| Observability | JSON logs, error rate, alerts और retention defined हैं |
| Cleanup | delete commands या dashboard steps documented हैं |
zip function.zip index.mjs
aws lambda update-function-code \
--function-name serverless-orders-dev \
--zip-file fileb://function.zip
npx wrangler deploy
Final review prompt:
इस serverless function को publish से पहले review करें।
blocking issues, non-blocking improvements और human confirmations अलग करें।
idempotency, timeout/retry, secrets, IAM या bindings, logs,
local reproducibility, cleanup, official links और internal links check करें।
ClaudeCodeLab इस तरह के patterns को Claude Code products and templates में organize करता है। Team rollout में AWS permissions, CLAUDE.md, review prompts और deployment approvals design करने हों तो Claude Code training and consultation देखें।
इस workflow को आजमाने पर सबसे बड़ा practical gain event fixture पहले बनाने से मिला। Claude Code तेज है, लेकिन retries, secrets और cleanup तभी reliable होते हैं जब वे first prompt में साफ लिखे हों।
मुफ़्त PDF: Claude Code cheatsheet
Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.
हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.
लेखक के बारे में
Masa
Claude Code workflow और team adoption पर काम करने वाला engineer.
संबंधित लेख
Claude Code Obsidian to CLAUDE.md workflow: context बार-बार न समझाएं
Obsidian notes को CLAUDE.md operating notes में बदलकर Claude Code sessions को resume करना आसान बनाएं.
Claude Code Revenue CTA Routing: article से PDF, Gumroad और consultation तक
Reader intent के आधार पर free PDF, Gumroad products और consultation तक CTA route करने वाला workflow.
Claude Code टीम हैंडऑफ नियम: review proof, permissions, rollback और revenue path
Claude Code टीम काम के लिए evidence, permission rules, rollback, free PDF, Gumroad और consultation path वाला handoff.