Claude Code से Microservices: boundaries, APIs, Compose और testing
Claude Code microservices: boundaries, API contracts, Compose, tests, observability और rollout.
Microservices वह डिजाइन है जिसमें एक बड़े application को छोटे, स्वतंत्र services में बांटा जाता है और वे APIs या events से एक-दूसरे से जुड़ते हैं। Claude Code तब ज्यादा उपयोगी होता है जब आप उससे केवल folders generate नहीं कराते, बल्कि service boundaries, API contracts, database ownership, local Docker Compose, gateway, observability, tests और rollout checklist भी review कराते हैं।
साफ बात: microservices अपने-आप performance नहीं बढ़ाते। Split करते ही network failure, API compatibility, distributed transaction, log correlation और rollback planning जैसी नई जिम्मेदारियां आ जाती हैं। अगर domain अभी रोज बदल रहा है, तो modular monolith बेहतर शुरुआत हो सकता है। आधार के लिए Claude Code API development, Docker Compose guide, logging और monitoring और event-driven architecture भी देखें।
Official references को review anchor बनाइए: Anthropic Claude Code overview, Docker Compose documentation और OpenAPI Specification 3.1. इससे Claude Code की suggestion और आपकी production contract अलग-अलग दिखती है।
पहले Service Boundary तय करें
Claude Code से सीधे “इसे microservices में बदल दो” न कहें। उसे business capability, data ownership और failure mode समझाने को कहें।
आप e-commerce application को microservices में बांटने वाले architecture reviewer हैं।
Context:
- Order flow बार-बार बदलता है।
- Inventory warehouse integration के कारण अलग deploy होना चाहिए।
- Payment और notification failure से catalog browsing बंद नहीं होनी चाहिए।
Output:
1. Candidate services और responsibilities.
2. हर service के owned data.
3. कौन-सा interaction synchronous API होगा.
4. कौन-सा interaction async event होगा.
5. पहले sprint का minimum Docker Compose setup.
Rules:
- Shared database tables नहीं.
- Internal table names API में नहीं.
- Gateway में business logic नहीं.
Microsoft Learn का Microservices architecture guide service autonomy और data isolation समझने के लिए अच्छा reference है। Kubernetes deployment की दिशा में सोच रहे हैं तो AKS microservices reference architecture देखें। Gateway की भूमिका के लिए API Management gateway overview उपयोगी है।
API Contract और Data Ownership
Handler code से पहले contract लिखें।
openapi: 3.1.0
info:
title: Order Service API
version: 1.0.0
paths:
/orders:
post:
summary: Create an order after reserving inventory
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [customerId, items]
properties:
customerId:
type: string
items:
type: array
minItems: 1
items:
type: object
required: [sku, quantity]
properties:
sku:
type: string
quantity:
type: integer
minimum: 1
responses:
"201":
description: Order accepted
"409":
description: Inventory could not be reserved
| Service | Owns | May call | Must not do |
|---|---|---|---|
| gateway | कोई business data नहीं | order, inventory | stock या discount calculate |
| order-service | orders, order_items | inventory API, order-events | inventory tables read |
| inventory-service | stock, reservations | शुरुआत में कुछ नहीं | orders tables read |
| notification-service | delivery logs | order-events | order status direct change |
अगर एक screen को order और stock दोनों चाहिए, तो service databases के बीच JOIN न करें। API composition, read model, search index या event-driven cache चुनें।
Review के लिए repository में छोटा service-inventory.json रखें। Boundary human तय करे; Claude Code यह check करे कि कोई change उस boundary को तोड़ तो नहीं रहा।
{
"services": [
{
"name": "gateway",
"owns": [],
"mayCall": ["order-service", "inventory-service"],
"mustNot": ["store business data", "calculate discounts"]
},
{
"name": "order-service",
"owns": ["orders", "order_items"],
"mayCall": ["inventory-service"],
"mustNot": ["read inventory tables directly"]
},
{
"name": "inventory-service",
"owns": ["stock", "reservations"],
"mayCall": [],
"mustNot": ["change order status"]
}
],
"releaseRules": [
"no shared database tables",
"public APIs hide internal table names",
"every service has healthcheck, logs, tests, and rollback notes"
]
}
Copy-Paste Runnable Example
mkdir microservices-demo
cd microservices-demo
mkdir services
npm init -y
npm pkg set type=module
npm install express zod pino redis undici
compose.yaml:
services:
gateway:
image: node:22-alpine
working_dir: /workspace
command: node services/service.mjs
environment:
SERVICE: gateway
PORT: 3000
ORDER_URL: http://order-service:3000
INVENTORY_URL: http://inventory-service:3000
ports:
- "8080:3000"
volumes:
- .:/workspace
depends_on:
- order-service
- inventory-service
order-service:
image: node:22-alpine
working_dir: /workspace
command: node services/service.mjs
environment:
SERVICE: order
PORT: 3000
INVENTORY_URL: http://inventory-service:3000
REDIS_URL: redis://redis:6379
volumes:
- .:/workspace
depends_on:
redis:
condition: service_healthy
inventory-service:
condition: service_started
inventory-service:
image: node:22-alpine
working_dir: /workspace
command: node services/service.mjs
environment:
SERVICE: inventory
PORT: 3000
volumes:
- .:/workspace
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
services/service.mjs:
import express from "express";
import pino from "pino";
import { createClient } from "redis";
import { request } from "undici";
import { z } from "zod";
import { randomUUID } from "node:crypto";
const service = process.env.SERVICE ?? "inventory";
const port = Number(process.env.PORT ?? 3000);
const log = pino({ name: service });
function base(name) {
const app = express();
app.use(express.json());
app.use((req, res, next) => {
req.requestId = req.header("x-request-id") ?? randomUUID();
res.setHeader("x-request-id", req.requestId);
next();
});
app.get("/health", (_req, res) => res.json({ ok: true, service: name }));
return app;
}
function inventory() {
const app = base("inventory");
const stock = new Map([["sku-1", 5], ["sku-2", 2]]);
const Reserve = z.object({ sku: z.string().min(1), quantity: z.number().int().positive() });
app.get("/inventory/:sku", (req, res) => res.json({ sku: req.params.sku, quantity: stock.get(req.params.sku) ?? 0 }));
app.post("/inventory/reservations", (req, res) => {
const parsed = Reserve.safeParse(req.body);
if (!parsed.success) return res.status(400).json({ error: parsed.error.flatten() });
const available = stock.get(parsed.data.sku) ?? 0;
if (available < parsed.data.quantity) return res.status(409).json({ error: "insufficient_stock", available });
stock.set(parsed.data.sku, available - parsed.data.quantity);
log.info({ requestId: req.requestId, sku: parsed.data.sku }, "reserved");
res.status(201).json({ sku: parsed.data.sku, remaining: stock.get(parsed.data.sku) });
});
app.listen(port, () => log.info({ port }, "inventory started"));
}
async function order() {
const app = base("order");
const redis = createClient({ url: process.env.REDIS_URL ?? "redis://localhost:6379" });
await redis.connect();
const Order = z.object({
customerId: z.string().min(1),
items: z.array(z.object({ sku: z.string().min(1), quantity: z.number().int().positive() })).min(1),
});
app.post("/orders", async (req, res) => {
const parsed = Order.safeParse(req.body);
if (!parsed.success) return res.status(400).json({ error: parsed.error.flatten() });
for (const item of parsed.data.items) {
const response = await request(`${process.env.INVENTORY_URL}/inventory/reservations`, {
method: "POST",
headers: { "content-type": "application/json", "x-request-id": req.requestId },
body: JSON.stringify(item),
});
if (response.statusCode >= 400) return res.status(response.statusCode).json(await response.body.json());
}
const order = { id: randomUUID(), ...parsed.data, status: "accepted" };
await redis.xAdd("order-events", "*", { type: "OrderAccepted", payload: JSON.stringify(order) });
res.status(201).json(order);
});
app.listen(port, () => log.info({ port }, "order started"));
}
function gateway() {
const app = base("gateway");
async function forward(req, res, url) {
const response = await request(url, {
method: req.method,
headers: { "content-type": "application/json", "x-request-id": req.requestId },
body: req.method === "GET" ? undefined : JSON.stringify(req.body),
});
res.status(response.statusCode).send(await response.body.text());
}
app.post("/orders", (req, res) => forward(req, res, `${process.env.ORDER_URL}/orders`));
app.get("/inventory/:sku", (req, res) => forward(req, res, `${process.env.INVENTORY_URL}/inventory/${encodeURIComponent(req.params.sku)}`));
app.listen(port, () => log.info({ port }, "gateway started"));
}
if (service === "inventory") inventory();
else if (service === "order") await order();
else if (service === "gateway") gateway();
Run:
docker compose up
curl http://localhost:8080/inventory/sku-1
curl -X POST http://localhost:8080/orders -H "content-type: application/json" -d '{"customerId":"cust-1","items":[{"sku":"sku-1","quantity":2}]}'
docker compose down
Go Live से पहले Decision Criteria
Production में जाने से पहले सिर्फ services की संख्या मत गिनिए. हर service के पास data owner, API contract, contract test, health endpoint, structured logs और rollback path होना चाहिए. Claude Code से एक business workflow को checklist में बदलवाइए और पूछिए कि कौन सा failure retry होगा और कौन सा manual intervention मांगेगा.
Observability, Testing और Rollout
पहले sprint से ही x-request-id, structured logs, service name, business IDs, /health, error rate और latency रखें। Claude Code से API compatibility, migration ownership, gateway में business logic न होना, 400/409/500 paths, Redis failure, feature flags, canary और rollback review कराएं।
अच्छे use cases हैं: e-commerce में order, inventory, payment, notification; B2B SaaS में billing, permission, audit logs; content platform में ingestion, transformation, search और delivery। Common pitfalls हैं: table के हिसाब से services बनाना, shared database, बहुत बड़ी shared domain library, gateway में rules डालना, और monitoring के बिना release करना।
अगर आपको CLAUDE.md snippets, review checklists और API contract templates बार-बार reuse करने हैं, तो ClaudeCodeLab के practical products से शुरुआत करें।
अगर आपकी team real code पर boundaries, API contracts, Compose और monitoring review करना चाहती है, तो Claude Code training and consultation से एक छोटे workflow पर शुरुआत करें।
मुफ़्त PDF: Claude Code cheatsheet
Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.
हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.
लेखक के बारे में
Masa
Claude Code workflow और team adoption पर काम करने वाला engineer.
संबंधित लेख
Claude Code Permission Receipt Pattern: scope, proof और rollback लिखना
Claude Code के लिए permission receipt: allowed actions, approval boundary, verification commands, rollback note और revenue CTA checks।
Claude Code और Codex के लिए सुरक्षित Agent Harness: permissions, verification और rollback
Claude Code और Codex agents के लिए सुरक्षित harness: permissions, plan, verification और rollback.
Claude Code Subagents गाइड: article और code work को सुरक्षित तरीके से delegate करें
Claude Code subagents से article और code work बांटें: delegation rules, prompts, pitfalls, checklist और examples.