Backend Patterns Skill
Purpose
Implement production-ready backend services with proper patterns.
Framework Selection
| Language |
Framework |
Best For |
| Node.js |
Express |
Simple APIs, quick prototypes |
| Node.js |
NestJS |
Enterprise, TypeScript |
| Node.js |
Fastify |
High performance |
| Python |
FastAPI |
Modern async, auto-docs |
| Python |
Django |
Full-featured, admin |
| Go |
Gin |
Fast, middleware |
| Java |
Spring Boot |
Enterprise, ecosystem |
Error Handling Pattern
// Error hierarchy
class AppError extends Error {
constructor(
public code: string,
message: string,
public status: number = 500,
) {
super(message);
this.name = this.constructor.name;
}
}
class NotFoundError extends AppError {
constructor(resource: string, id: string) {
super('NOT_FOUND', `${resource} ${id} not found`, 404);
}
}
class ValidationError extends AppError {
constructor(public errors: { field: string; message: string }[]) {
super('VALIDATION_ERROR', 'Validation failed', 400);
}
}
// Global handler
app.use((err, req, res, next) => {
if (err instanceof AppError) {
return res.status(err.status).json({
type: `https://api.example.com/errors/${err.code.toLowerCase()}`,
title: err.message,
status: err.status,
});
}
logger.error(err);
res.status(500).json({ title: 'Internal error', status: 500 });
});
Middleware Pattern
// Request ID middleware
const requestId = (req, res, next) => {
req.id = req.headers['x-request-id'] || crypto.randomUUID();
res.setHeader('X-Request-ID', req.id);
next();
};
// Logging middleware
const requestLogger = (req, res, next) => {
const start = Date.now();
res.on('finish', () => {
logger.info({
method: req.method,
path: req.path,
status: res.statusCode,
duration: Date.now() - start,
requestId: req.id,
});
});
next();
};
// Error boundary
const asyncHandler = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
Validation Pattern
import { z } from 'zod';
const CreateUserSchema = z.object({
email: z.string().email(),
name: z.string().min(1).max(100),
password: z.string().min(12),
});
function validate(schema) {
return (req, res, next) => {
const result = schema.safeParse(req.body);
if (!result.success) {
throw new ValidationError(
result.error.issues.map(i => ({
field: i.path.join('.'),
message: i.message,
}))
);
}
req.body = result.data;
next();
};
}
app.post('/users', validate(CreateUserSchema), createUser);
Graceful Shutdown
const server = app.listen(3000);
async function shutdown() {
console.log('Shutting down...');
// Stop accepting new connections
server.close();
// Close database connections
await db.destroy();
// Close Redis
await redis.quit();
process.exit(0);
}
process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);
Unit Test Template
describe('Backend Pattern: Error Handling', () => {
it('should return proper error response', async () => {
const res = await request(app)
.get('/users/invalid-id')
.expect(404);
expect(res.body).toMatchObject({
type: expect.stringContaining('not-found'),
status: 404,
});
});
});
Troubleshooting
| Issue |
Cause |
Solution |
| Memory leak |
Event listeners |
Remove on cleanup |
| Connection timeout |
Pool exhausted |
Increase pool size |
| Unhandled rejection |
Missing catch |
Add async handler |
Quality Checklist
1---2name: backend-patterns3version: "2.0.0"4description: Production-grade backend patterns for Node.js, Python, Go, and Java/Spring frameworks5sasmp_version: "1.3.0"6bonded_agent: 02-backend-patterns7bond_type: PRIMARY_BOND89# Skill Configuration10atomic_design:11 single_responsibility: "Backend implementation patterns and frameworks"12 boundaries:13 includes: [nodejs, python, go, java, error_handling, middleware, async]14 excludes: [api_design, database_queries, infrastructure]1516parameter_validation:17 schema:18 type: object19 properties:20 language:21 type: string22 enum: [nodejs, python, go, java]23 framework:24 type: string25 pattern:26 type: string27 enum: [middleware, error_handling, validation, logging]2829retry_config:30 enabled: true31 max_attempts: 332 backoff:33 type: exponential34 initial_delay_ms: 100035 max_delay_ms: 300003637logging:38 level: INFO39 fields: [language, framework, pattern, duration_ms]4041dependencies:42 skills: []43 agents: [02-backend-patterns]44---4546# Backend Patterns Skill4748## Purpose49Implement production-ready backend services with proper patterns.5051## Framework Selection5253| Language | Framework | Best For |54|----------|-----------|----------|55| Node.js | Express | Simple APIs, quick prototypes |56| Node.js | NestJS | Enterprise, TypeScript |57| Node.js | Fastify | High performance |58| Python | FastAPI | Modern async, auto-docs |59| Python | Django | Full-featured, admin |60| Go | Gin | Fast, middleware |61| Java | Spring Boot | Enterprise, ecosystem |6263## Error Handling Pattern6465```typescript66// Error hierarchy67class AppError extends Error {68 constructor(69 public code: string,70 message: string,71 public status: number = 500,72 ) {73 super(message);74 this.name = this.constructor.name;75 }76}7778class NotFoundError extends AppError {79 constructor(resource: string, id: string) {80 super('NOT_FOUND', `${resource} ${id} not found`, 404);81 }82}8384class ValidationError extends AppError {85 constructor(public errors: { field: string; message: string }[]) {86 super('VALIDATION_ERROR', 'Validation failed', 400);87 }88}8990// Global handler91app.use((err, req, res, next) => {92 if (err instanceof AppError) {93 return res.status(err.status).json({94 type: `https://api.example.com/errors/${err.code.toLowerCase()}`,95 title: err.message,96 status: err.status,97 });98 }99 logger.error(err);100 res.status(500).json({ title: 'Internal error', status: 500 });101});102```103104## Middleware Pattern105106```typescript107// Request ID middleware108const requestId = (req, res, next) => {109 req.id = req.headers['x-request-id'] || crypto.randomUUID();110 res.setHeader('X-Request-ID', req.id);111 next();112};113114// Logging middleware115const requestLogger = (req, res, next) => {116 const start = Date.now();117 res.on('finish', () => {118 logger.info({119 method: req.method,120 path: req.path,121 status: res.statusCode,122 duration: Date.now() - start,123 requestId: req.id,124 });125 });126 next();127};128129// Error boundary130const asyncHandler = (fn) => (req, res, next) => {131 Promise.resolve(fn(req, res, next)).catch(next);132};133```134135## Validation Pattern136137```typescript138import { z } from 'zod';139140const CreateUserSchema = z.object({141 email: z.string().email(),142 name: z.string().min(1).max(100),143 password: z.string().min(12),144});145146function validate(schema) {147 return (req, res, next) => {148 const result = schema.safeParse(req.body);149 if (!result.success) {150 throw new ValidationError(151 result.error.issues.map(i => ({152 field: i.path.join('.'),153 message: i.message,154 }))155 );156 }157 req.body = result.data;158 next();159 };160}161162app.post('/users', validate(CreateUserSchema), createUser);163```164165## Graceful Shutdown166167```typescript168const server = app.listen(3000);169170async function shutdown() {171 console.log('Shutting down...');172173 // Stop accepting new connections174 server.close();175176 // Close database connections177 await db.destroy();178179 // Close Redis180 await redis.quit();181182 process.exit(0);183}184185process.on('SIGTERM', shutdown);186process.on('SIGINT', shutdown);187```188189---190191## Unit Test Template192193```typescript194describe('Backend Pattern: Error Handling', () => {195 it('should return proper error response', async () => {196 const res = await request(app)197 .get('/users/invalid-id')198 .expect(404);199200 expect(res.body).toMatchObject({201 type: expect.stringContaining('not-found'),202 status: 404,203 });204 });205});206```207208---209210## Troubleshooting211212| Issue | Cause | Solution |213|-------|-------|----------|214| Memory leak | Event listeners | Remove on cleanup |215| Connection timeout | Pool exhausted | Increase pool size |216| Unhandled rejection | Missing catch | Add async handler |217218---219220## Quality Checklist221222- [ ] Error handling standardized223- [ ] Request logging enabled224- [ ] Input validation implemented225- [ ] Graceful shutdown configured226- [ ] Health check endpoint