Backend Development Guidelines
- Implementing middleware (auth, validation, error handling)
Category: design Source: diet103/claude-code-infrastructure-showcaseWhat Is This
The "Backend Development Guidelines" skill provides a standardized set of best practices and architectural patterns for building robust, scalable backend microservices using Node.js, Express, and TypeScript. It is specifically designed for teams working with a layered architecture (routes, controllers, services, repositories) and modern tooling such as Prisma for database access, Sentry for error tracking, Zod for input validation, and dependency injection for maintainable codebases. This skill acts as a reference and checklist for implementing middleware (authentication, validation, error handling), and structuring backend logic in a consistent, testable manner across microservices such as blog APIs, authentication services, and notification systems.
Why Use It
Consistency and reliability are crucial in backend development, especially when multiple teams or developers collaborate on large codebases. Without clear guidelines, projects can quickly become difficult to maintain, debug, or extend. The Backend Development Guidelines skill addresses these challenges by:
- Encouraging a uniform project structure, making code easier to read and maintain
- Promoting separation of concerns through layered architecture (routes, controllers, services, repositories)
- Ensuring robust input validation and error handling via Zod and Sentry
- Recommending best practices for middleware implementation (authentication, validation, error logging)
- Facilitating performance monitoring and testing strategies for higher code quality
- Providing migration steps for refactoring legacy codebases into modern patterns
By adhering to these guidelines, teams can reduce bugs, improve security, and streamline onboarding for new developers.
How to Use It
This skill activates automatically when you are working on backend features, particularly when you:
- Create or modify Express routes, endpoints, or APIs
- Build controllers, services, or repositories
- Implement authentication, input validation, or error handling middleware
- Integrate Prisma for database operations
- Set up Sentry for error tracking or Zod for schema validation
- Refactor or test backend logic
1. Layered Architecture Overview
Organize your codebase using the following layers:
- Routes: Define HTTP endpoints, delegate logic to controllers.
- Controllers: Extend a
BaseControllerclass. Handle request lifecycle, validation, and error propagation. - Services: Contain business logic, use dependency injection for testability.
- Repositories: Encapsulate database access. Use only when queries are complex or reused.
Example folder structure:
/src
/routes
/controllers
/services
/repositories
/middleware
2. Middleware Implementation
Implement middleware for authentication, input validation, and error handling.
Authentication middleware example:
import { Request, Response, NextFunction } from 'express';
export function authenticate(req: Request, res: Response, next: NextFunction) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
// Token verification logic here
next();
}
Validation middleware with Zod:
import { Request, Response, NextFunction } from 'express';
import { z } from 'zod';
const userSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
});
export function validateUser(req: Request, res: Response, next: NextFunction) {
try {
userSchema.parse(req.body);
next();
} catch (err) {
res.status(400).json({ error: err.errors });
}
}
Error handling middleware:
import { Request, Response, NextFunction } from 'express';
import * as Sentry from '@sentry/node';
export function errorHandler(err: Error, req: Request, res: Response, next: NextFunction) {
Sentry.captureException(err);
res.status(500).json({ error: 'Internal Server Error' });
}
3. Controller and Service Patterns
Controllers should extend a BaseController, providing consistent request handling.
Example controller:
import { Request, Response } from 'express';
import { BaseController } from './BaseController';
import { UserService } from '../services/UserService';
export class UserController extends BaseController {
constructor(private userService: UserService) {
super();
}
async createUser(req: Request, res: Response) {
const user = await this.userService.create(req.body);
this.ok(res, user);
}
}
Services encapsulate business logic and interact with repositories.
4. Prisma and Dependency Injection
Use Prisma in repository classes for complex database operations. Inject repositories into services and services into controllers to maximize testability.
Example repository:
import { PrismaClient } from '@prisma/client';
export class UserRepository {
constructor(private prisma: PrismaClient) {}
async findByEmail(email: string) {
return this.prisma.user.findUnique({ where: { email } });
}
}
5. Testing and Error Tracking
- Write unit tests for services and controllers.
- Write integration tests for routes.
- Use Sentry in error handling middleware for centralized error monitoring.
When to Use It
Use this skill whenever you:
- Build or refactor Express endpoints or APIs
- Implement new middleware for authentication, validation, or error handling
- Add or update controllers, services, or repositories
- Perform database operations with Prisma
- Enhance error monitoring with Sentry
- Add or update schema validation with Zod
- Migrate legacy code to modern Node.js/Express/TypeScript structures
Important Notes
- Always validate input using Zod before passing data to controllers or services.
- Extend controllers from a
BaseControllerto enforce consistent response methods (e.g.,ok,error). - Use dependency injection for services and repositories to improve testability and decouple components.
- Handle all errors through centralized middleware and report to Sentry.
- Follow the folder structure and layering guidelines strictly for maintainability.
- Regularly review and update tests to cover new features and edge cases.
- Use repositories only for complex or reusable database operations - simple queries can remain in services.
By following these backend development guidelines, you ensure a maintainable, scalable, and robust backend architecture across your Node.js/Express/TypeScript microservices.