backend-coding
Backend Coding
Build production-ready backend services with proper architecture, security, performance optimization, and testing.
Core Development Workflow
Follow this systematic approach for backend implementation:
1. Design API Endpoints
Define clear, RESTful API contracts before implementation.
REST API Design Pattern:
Resource-based URLs (use plural nouns):
✅ GET /api/v1/users - List users (paginated)
✅ GET /api/v1/users/:id - Get user by ID
✅ POST /api/v1/users - Create new user
✅ PUT /api/v1/users/:id - Replace entire user
✅ PATCH /api/v1/users/:id - Update user fields
✅ DELETE /api/v1/users/:id - Delete user
❌ Avoid verb-based URLs:
❌ /api/v1/getUsers
❌ /api/v1/createUser
Basic Example (Express.js):
router.get('/users',
query('page').optional().isInt({ min: 1 }).toInt(),
query('limit').optional().isInt({ min: 1, max: 100 }).toInt(),
async (req, res, next) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const page = req.query.page as number || 1;
const limit = req.query.limit as number || 20;
const offset = (page - 1) * limit;
const { users, total } = await userService.findAll({
limit, offset
});
res.json({
data: users,
pagination: { page, limit, total }
});
} catch (error) {
next(error);
}
}
);
For complete patterns: api-design.md
2. Implement Database Layer
Use repository pattern for clean separation and testability.
Repository Pattern (TypeORM):
export class UserRepository {
private repository: Repository<User>;
async findAll(params: { search?: string; limit: number; offset: number }) {
const queryBuilder = this.repository
.createQueryBuilder('user')
.orderBy('user.createdAt', 'DESC');
if (params.search) {
queryBuilder.where(
'user.name ILIKE :search OR user.email ILIKE :search',
{ search: `%${params.search}%` }
);
}
return queryBuilder
.take(params.limit)
.skip(params.offset)
.getManyAndCount();
}
async create(userData: UserCreate): Promise<User> {
const hashedPassword = await bcrypt.hash(userData.password, 12);
const user = this.repository.create({
...userData,
password: hashedPassword
});
return this.repository.save(user);
}
}
For detailed patterns: database-patterns.md
3. Implement Authentication
Secure JWT-based authentication with refresh tokens.
JWT Authentication Pattern:
export class AuthService {
private readonly JWT_SECRET = process.env.JWT_SECRET!;
private readonly ACCESS_TOKEN_EXPIRY = '15m';
private readonly REFRESH_TOKEN_EXPIRY = '7d';
async login(email: string, password: string) {
const user = await userRepository.findByEmail(email);
if (!user || !await bcrypt.compare(password, user.password)) {
throw new UnauthorizedError('Invalid credentials');
}
const accessToken = this.generateAccessToken(user);
const refreshToken = this.generateRefreshToken(user);
await tokenRepository.create({
userId: user.id,
token: refreshToken,
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
});
return { accessToken, refreshToken, user };
}
generateAccessToken(user: User): string {
return jwt.sign(
{ userId: user.id, email: user.email, role: user.role },
this.JWT_SECRET,
{ expiresIn: this.ACCESS_TOKEN_EXPIRY }
);
}
}
// Middleware
export const authenticate = async (req, res, next) => {
const token = req.headers.authorization?.substring(7);
if (!token) {
return res.status(401).json({ error: 'Missing token' });
}
try {
req.user = authService.verifyAccessToken(token);
next();
} catch (error) {
res.status(401).json({ error: 'Invalid token' });
}
};
For complete implementation: authentication-and-authorization.md
4. Implement Caching
Use Redis for performance optimization with cache-aside pattern.
Caching Pattern:
export class CacheService {
private redis: Redis;
private readonly DEFAULT_TTL = 3600; // 1 hour
async getOrSet<T>(
key: string,
fetchFn: () => Promise<T>,
ttl: number = this.DEFAULT_TTL
): Promise<T> {
// Try cache first
const cached = await this.redis.get(key);
if (cached) return JSON.parse(cached);
// Fetch from database
const data = await fetchFn();
await this.redis.setex(key, ttl, JSON.stringify(data));
return data;
}
async invalidate(pattern: string): Promise<void> {
const keys = await this.redis.keys(pattern);
if (keys.length > 0) await this.redis.del(...keys);
}
}
// Usage in service
export class UserService {
async findById(id: string): Promise<User | null> {
return cache.getOrSet(
`user:${id}`,
() => repository.findById(id),
3600
);
}
async update(id: string, updates: Partial<User>): Promise<User | null> {
const user = await repository.update(id, updates);
await cache.invalidate(`user:${id}`);
await cache.invalidate(`users:list:*`);
return user;
}
}
For advanced strategies: caching-strategies.md
5. Implement Error Handling
Global error handling with custom error classes.
Error Handling Pattern:
// Custom error classes
export class AppError extends Error {
constructor(
public statusCode: number,
message: string,
public isOperational: boolean = true
) {
super(message);
Error.captureStackTrace(this, this.constructor);
}
}
export class ValidationError extends AppError {
constructor(message: string, public errors: any[]) {
super(400, message);
}
}
export class UnauthorizedError extends AppError {
constructor(message: string = 'Unauthorized') {
super(401, message);
}
}
export class NotFoundError extends AppError {
constructor(message: string = 'Resource not found') {
super(404, message);
}
}
// Global error handler middleware
export const errorHandler = (err: Error, req: Request, res: Response, next: NextFunction) => {
if (err instanceof AppError) {
return res.status(err.statusCode).json({
error: { message: err.message }
});
}
console.error('Unexpected error:', err);
res.status(500).json({ error: { message: 'Internal server error' } });
};
// Async handler wrapper
export const asyncHandler = (fn: Function) => {
return (req: Request, res: Response, next: NextFunction) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
};
6. Write Tests
Write comprehensive unit and integration tests.
Testing Pattern:
describe('User API', () => {
beforeAll(async () => {
await AppDataSource.initialize();
});
afterAll(async () => {
await AppDataSource.destroy();
});
beforeEach(async () => {
await AppDataSource.synchronize(true);
});
describe('POST /api/v1/users', () => {
it('should create a new user', async () => {
const response = await request(app)
.post('/api/v1/users')
.send({
email: 'test@example.com',
password: 'SecurePass123!',
name: 'Test User'
})
.expect(201);
expect(response.body.data).toMatchObject({
email: 'test@example.com',
name: 'Test User'
});
expect(response.body.data.password).toBeUndefined();
});
it('should return 400 for invalid email', async () => {
await request(app)
.post('/api/v1/users')
.send({
email: 'invalid-email',
password: 'SecurePass123!',
name: 'Test User'
})
.expect(400);
});
});
});
Framework-Specific Guides
Load detailed implementation guides for specific frameworks:
- nodejs-development.md - Express, NestJS, Fastify, middleware, async handling
- python-development.md - Django, Flask, FastAPI, async/await, decorators
Technology-Specific Patterns
Load detailed patterns for specific technologies:
- api-design.md - REST, GraphQL, gRPC, versioning, documentation
- database-patterns.md - ORMs, query optimization, transactions, migrations
- authentication-and-authorization.md - JWT, OAuth, RBAC, session management
- caching-strategies.md - Redis patterns, cache invalidation, distributed caching
- microservices.md - Service communication, API gateways, circuit breakers
Production-Ready Checklist
Before deployment, verify:
Security:
☐ Input validation on all endpoints (express-validator, Pydantic)
☐ SQL injection prevention (parameterized queries only)
☐ Password hashing with bcrypt/argon2 (cost factor ≥12)
☐ JWT tokens expire within 15 minutes, refresh tokens within 7 days
☐ Rate limiting: 100 req/min per user, 1000 req/min per IP
☐ CORS configured (not '*' in production)
☐ Environment variables for all secrets
☐ HTTPS only (TLS 1.3 minimum)
Performance:
☐ Database indexes on query columns
☐ Connection pooling configured (10-20 connections)
☐ Caching frequently accessed data (Redis, 1-hour TTL)
☐ Pagination for large result sets (limit ≤100 items)
☐ Async operations for I/O (non-blocking)
Code Quality:
☐ Repository pattern for data access
☐ Dependency injection for testability
☐ Global error handling with custom error classes
☐ Structured logging with request IDs
☐ Test coverage ≥80% (unit + integration)
☐ API documentation (OpenAPI/Swagger)
☐ Health check endpoint (/health)
☐ Graceful shutdown handling
Critical Security Principles
Never trust user input - Validate everything Use parameterized queries - Prevent SQL injection Hash passwords - bcrypt with cost factor 12+, never store plain text Expire tokens quickly - 15min access tokens, 7day refresh tokens Use HTTPS only - TLS 1.3 minimum
Critical Performance Principles
Cache frequently accessed data - Redis with appropriate TTL (typically 1 hour) Use database indexes - On all query columns Paginate large result sets - Max 100 items per page Use connection pooling - 10-20 connections Async operations for I/O - Don't block the event loop
More from dauquangthanh/hanoi-rainbow
requirements-gathering
Guides comprehensive requirements gathering and analysis including stakeholder interviews, user story creation, use case documentation, acceptance criteria, requirements prioritization, and traceability. Produces requirements documents, user stories, use cases, and development roadmaps. Use when gathering requirements, writing user stories, creating acceptance criteria, analyzing stakeholder needs, prioritizing features, or when users mention requirements analysis, business analysis, user stories, use cases, or requirements documentation.
25frontend-coding
Expert frontend development guidance covering React, Vue, Angular, TypeScript, state management, component architecture, performance optimization, accessibility, testing, and modern web APIs. Produces production-ready, maintainable, and performant frontend code with best practices. Use when building web applications, implementing UI components, managing application state, optimizing performance, or when users mention React, Vue, Angular, TypeScript, hooks, state management, components, or frontend development.
19mockup-creation
Create interactive, production-ready UI mockups and prototypes using NuxtJS 4 (Vue) or Next.js (React), TypeScript, and TailwindCSS v4. Use when building web mockups, prototypes, landing pages, dashboards, admin panels, or interactive UI demonstrations. Trigger when users mention "create mockup", "build prototype", "interactive demo", "UI prototype", "design to code", or need rapid frontend development with modern tooling. Prefer NuxtJS for Vue-based projects; use Next.js when users mention ReactJS.
18frontend-code-review
Conducts comprehensive frontend code reviews including React/Vue/Angular component analysis, TypeScript/JavaScript quality assessment, CSS/styling review, performance optimization, accessibility compliance, security vulnerabilities, and best practices validation. Produces detailed review reports with specific issues, severity ratings, and actionable recommendations. Use when reviewing frontend code, analyzing React/Vue/Angular components, checking JavaScript/TypeScript quality, validating CSS/SCSS, assessing web performance, or when users mention "review frontend code", "check React components", "analyze JavaScript", "review TypeScript", "validate accessibility", or "frontend code quality".
15aws-cloud
Provides comprehensive AWS (Amazon Web Services) guidance including EC2, S3, RDS, Lambda, ECS/EKS, CloudFormation, API Gateway, CloudFront, cloud migration from on-premise/GCP/Azure, security configuration (IAM, KMS, Security Hub), cost optimization (Savings Plans, Reserved Instances), and multi-region deployment. Produces infrastructure as code (Terraform/CloudFormation/CDK), deployment scripts, security configurations, and architecture designs. Use when deploying to AWS, designing AWS infrastructure, migrating to AWS, configuring EC2 instances, setting up S3 buckets, managing RDS databases, deploying containers on ECS/EKS, building serverless applications, or when users mention AWS, Amazon Cloud, EC2, S3, Lambda, EKS, CloudFormation, CDK, or AWS services.
15system-migration
Guides operating system and hardware platform migrations including Linux distribution changes, Windows to Linux migration, mainframe to x86 modernization, data center migrations (physical to virtual, P2V, V2V), hardware platform changes, system consolidation, and legacy system decommissioning. Covers OS compatibility, driver migration, system configuration transfer, and cutover procedures. Use when migrating operating systems, changing hardware platforms, moving from mainframes, or when users mention "OS migration", "Linux migration", "mainframe modernization", "P2V migration", "system upgrade", "data center migration", or "legacy system replacement".
15