

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# API Microservices Architecture — Cursor Rules2# Microservices patterns: service design, inter-service communication, Docker, and observability34# Project Context5You are building a microservices-based system. Each service is independently deployable, owns its6data, and communicates via well-defined APIs (REST/gRPC) and async messaging (events/queues).7The system uses Docker for containerization, and focuses on resilience, observability, and8loose coupling between services.910# Service Design Principles11- Each service owns one bounded context (domain). It owns its data and exposes it only via API.12- Services communicate through: synchronous APIs (REST/gRPC) and async events (message queues).13- Database per service — never share a database between services.14- Design for failure: every remote call can fail. Handle it gracefully.15- Keep services small enough to be understood by one team, large enough to be independently useful.1617# Service Structure (Per Service)18```19service-name/20 src/21 main.ts # Service entry point22 config/ # Service configuration23 api/24 routes.ts # Route definitions25 handlers/ # Request handlers26 middleware/ # Service-specific middleware27 domain/28 entities/ # Domain models29 services/ # Business logic30 events/ # Domain events (published)31 infrastructure/32 database/ # Database access, migrations33 messaging/ # Message queue publisher/consumer34 clients/ # External service clients35 shared/36 errors.ts37 logger.ts38 Dockerfile39 docker-compose.yml # Local development40 .env.example41 tests/42```4344# API Design Between Services45- Use RESTful APIs for synchronous request-response patterns.46- Use gRPC for high-performance, low-latency internal service calls.47- Version all APIs: `/api/v1/users`, never breaking changes on existing versions.48- Define API contracts with OpenAPI (REST) or Protocol Buffers (gRPC).49- Every service exposes a health check endpoint: `GET /health` returning `{ status: "ok" }`.50- Return consistent error responses across all services:51```json52 {53 "error": {54 "code": "USER_NOT_FOUND",55 "message": "User with ID 123 not found",56 "service": "user-service",57 "requestId": "req-abc-123"58 }59 }60```6162# Async Event-Driven Communication63- Use events for cross-service data propagation (eventual consistency):64```typescript65 // User service publishes:66 interface UserCreatedEvent {67 type: 'user.created';68 data: { userId: string; email: string; name: string };69 metadata: { timestamp: string; correlationId: string; service: string };70 }71```72- Use a message broker: RabbitMQ, Apache Kafka, or cloud-native (SQS/SNS, Pub/Sub).73- Events are facts about what happened — name them in past tense: `user.created`, `order.shipped`.74- Every event includes: type, data payload, timestamp, correlation ID, source service.75- Consumers must be idempotent — the same event delivered twice should not cause duplicate effects.76- Use dead-letter queues for events that fail processing after retries.77- DON'T: Put business logic in the event publisher — publish the fact, let consumers decide what to do.78- DON'T: Rely on event ordering across different event types.7980# Service Communication Resilience81- Implement circuit breaker pattern for synchronous calls:82```typescript83 // States: CLOSED (normal) -> OPEN (failing, reject calls) -> HALF_OPEN (testing recovery)84 const breaker = new CircuitBreaker(callUserService, {85 failureThreshold: 5,86 resetTimeout: 30000,87 fallback: () => cachedUserData,88 });89```90- Implement retry with exponential backoff for transient failures:91```typescript92 async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {93 for (let attempt = 0; attempt <= maxRetries; attempt++) {94 try { return await fn(); }95 catch (err) {96 if (attempt === maxRetries) throw err;97 await sleep(Math.pow(2, attempt) * 1000);98 }99 }100 }101```102- Set timeouts on all HTTP clients (connect: 3s, read: 10s).103- Implement bulkhead pattern: isolate resources so one failing dependency doesn't exhaust all threads.104- Use fallback strategies: cached data, default values, degraded functionality.105106# Docker Patterns107- Multi-stage Dockerfile for minimal production images:108```dockerfile109 FROM node:20-alpine AS builder110 WORKDIR /app111 COPY package*.json ./112 RUN npm ci113 COPY . .114 RUN npm run build115116 FROM node:20-alpine AS runner117 WORKDIR /app118 RUN addgroup -g 1001 appgroup && adduser -u 1001 -G appgroup -D appuser119 COPY --from=builder /app/dist ./dist120 COPY --from=builder /app/node_modules ./node_modules121 USER appuser122 EXPOSE 3000123 CMD ["node", "dist/main.js"]124```125- Run as non-root user in production containers.126- Use `.dockerignore` to exclude node_modules, .git, tests, docs.127- Use docker-compose for local development with all services + infrastructure.128- Health checks in docker-compose and Kubernetes manifests.129130# Service Discovery and Configuration131- Use environment variables for service URLs and configuration.132- In Kubernetes: use service DNS names (`http://user-service:3000`).133- In Docker Compose: use service names as hostnames.134- Externalize ALL configuration — no hardcoded URLs, ports, or credentials.135- Use a central config service or config maps for shared configuration.136137# Observability (The Three Pillars)138- **Logging**: Structured JSON logs with correlation IDs:139```json140 {"level":"info","service":"order-service","requestId":"req-123","correlationId":"corr-456","msg":"Order created","orderId":"ord-789"}141```142- **Metrics**: Expose Prometheus metrics at `/metrics`:143 - Request count, latency, error rate per endpoint.144 - Queue depth, processing time per event type.145 - Circuit breaker state, retry count.146- **Tracing**: Distributed tracing with OpenTelemetry:147 - Propagate trace context (traceparent header) across service calls.148 - Create spans for all significant operations (HTTP calls, DB queries, queue operations).149 - Include service name, operation, and error status in spans.150151# Data Consistency152- Accept eventual consistency between services — it's the trade-off for independence.153- Use the Saga pattern for distributed transactions:154 - Orchestration: a central coordinator manages the workflow steps.155 - Choreography: each service publishes events, next service reacts.156- Implement compensating transactions for rollback scenarios.157- Use outbox pattern for reliable event publishing: write event + business data in one DB transaction, then publish from outbox table.158159# Testing Microservices160- Unit tests: test business logic in isolation (mock external services).161- Integration tests: test one service with real database, mock other services.162- Contract tests: verify API contracts between consumer and provider (Pact).163- End-to-end tests: test critical paths through multiple services (use sparingly).164- Chaos testing: verify resilience by injecting failures (circuit breakers, timeouts).165166# Security Between Services167- Use mutual TLS (mTLS) for service-to-service authentication in production.168- Validate JWT tokens at the API gateway, pass verified claims to downstream services.169- Use network policies to restrict which services can communicate.170- Encrypt data in transit (TLS) and at rest (database encryption).171- Rotate secrets and certificates regularly — use a secrets manager (Vault, AWS Secrets Manager).172173# Common Mistakes to Avoid174- DON'T: Share databases between services — this creates tight coupling.175- DON'T: Make synchronous chains of 5+ service calls — use async events instead.176- DON'T: Skip idempotency in event consumers — duplicates will happen.177- DON'T: Deploy all services together — each must be independently deployable.178- DON'T: Use distributed transactions (2PC) — use sagas instead.179- DON'T: Ignore the fallacy of zero-latency network — every remote call adds latency and can fail.180- DON'T: Build microservices for a new product — start with a modular monolith, split later.181
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| survivorforge/cursor-rulesrules/ai-ml-python/.cursorrules · 16 | .cursorrules | teststylearchdeployment+2 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/langchain-ai/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+4 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/aws-serverless/.cursorrules · 16 | .cursorrules | teststylearchtypes+6 | 73/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/tailwindcss/.cursorrules · 16 | .cursorrules | lint-formatstylearchui+3 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/mern-stack/.cursorrules · 16 | .cursorrules | setupteststylearch+6 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/api-design-rest/.cursorrules · 16 | .cursorrules | lint-formatstylesecurityapi+3 | 69/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/chrome-extension/.cursorrules · 16 | .cursorrules | teststylearchtesting-strategy+4 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/clean-code/.cursorrules · 16 | .cursorrules | styledo-notagent-behaviourdocs | 57/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/database-sql/.cursorrules · 16 | .cursorrules | styletypessecuritydatabase+3 | 65/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/devops-docker/.cursorrules · 16 | .cursorrules | setupbuildteststyle+4 | 93/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/devops-infrastructure/.cursorrules · 16 | .cursorrules | buildteststylesecurity+3 | 93/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/django-rest/.cursorrules · 16 | .cursorrules | buildteststylearch+5 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/docker-devops/.cursorrules · 16 | .cursorrules | setupteststylearch+6 | 85/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/flutter-dart/.cursorrules · 16 | .cursorrules | teststylearchtypes+5 | 89/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/fullstack-nextjs-prisma/.cursorrules · 16 | .cursorrules | teststylearchtypes+7 | 96/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/go-gin/.cursorrules · 16 | .cursorrules | testlint-formatstylearch+5 | 84/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/mobile-react-native/.cursorrules · 16 | .cursorrules | teststylearchtypes+7 | 89/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-14-app-router/.cursorrules · 16 | .cursorrules | teststyletypestesting-strategy+3 | 71/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-app-router/.cursorrules · 16 | .cursorrules | teststylearchtypes+5 | 81/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/nextjs-typescript/.cursorrules · 16 | .cursorrules | teststylearchtypes+5 | 81/100 | 13 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| HerringtonDarkholme/megarepo.cursorrules · 17 | .cursorrules | setupbuildtestlint-format+13 | 96/100 | 14 days ago | |
| SkeneTechnologies/skene-cookbook.cursorrules · 51 | .cursorrules | setuptestlint-formatstyle+11 | 96/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/devops-docker/.cursorrules · 16 | .cursorrules | setupbuildteststyle+4 | 93/100 | 13 days ago | |
| survivorforge/cursor-rulesrules/devops-infrastructure/.cursorrules · 16 | .cursorrules | buildteststylesecurity+3 | 93/100 | 13 days ago | |
| fall-out-bug/sdp_lab.cursorrules · 0 | .cursorrules | setupbuildtestlint-format+3 | 86/100 | 14 days ago | |
| bashdeban/fastmind.cursorrules · 5 | .cursorrules | buildtestlint-formattypes+5 | 81/100 | 14 days ago | |
| storybookjs/storybook.cursorrules · 91k | .cursorrules | teststylearchdo-not+1 | 78/100 | 14 days ago | |
| forem/forem.cursorrules · 23k | .cursorrules | teststyletypesdatabase+4 | 71/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/survivorforge-cursor-rules-rules-api-microservices-cursorrules)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.