后端服务模式Skill backend-service-patterns

后端服务模式技能专注于设计和构建可扩展的后端应用程序,采用分层架构、依赖注入、中间件模式等核心原则。适用于API服务开发、业务逻辑实现、微服务架构、服务器less函数等场景,提升代码可维护性和可测试性。关键词:后端开发,API设计,微服务,架构模式,依赖注入,中间件,服务层,仓库模式。

后端开发 0 次安装 0 次浏览 更新于 3/18/2026

name: backend-service-patterns description: 使用分层架构、依赖注入、中间件模式、服务类和关注点分离来构建可扩展的后端服务。适用于构建API服务、实现业务逻辑层、创建服务类、设置中间件链、实施依赖注入、设计控制器-服务-仓库模式、处理跨领域关注点、创建领域模型、实现CQRS模式或建立后端架构标准。

后端服务模式 - 构建可扩展的服务器应用程序

何时使用此技能

  • 构建API服务和后端应用程序
  • 在服务层实现业务逻辑
  • 创建控制器-服务-仓库架构
  • 设置Express/Fastify中间件链
  • 实现依赖注入容器
  • 设计领域模型和业务实体
  • 处理跨领域关注点(日志、认证、验证)
  • 实现CQRS(命令查询职责分离)
  • 创建后台作业处理服务
  • 设计事件驱动服务架构
  • 实现API网关模式
  • 构建边界清晰的微服务

何时使用此技能

  • 设计后端架构、实现API、处理业务逻辑、管理微服务或构建服务器less函数。
  • 当处理相关任务或功能时
  • 在需要此专业知识的开发过程中

使用时:设计后端架构、实现API、处理业务逻辑、管理微服务或构建服务器less函数。

核心原则

  1. 关注点分离 - 各层之间清晰边界
  2. 单一职责 - 每个服务做好一件事
  3. 无状态设计 - 易于水平扩展
  4. 幂等性 - 操作可安全重试
  5. 快速失败,优雅恢复 - 明确处理错误

分层架构

1. 三层架构

// ✅ 路由层 - HTTP端点
// routes/users.ts
import express from 'express';
import { UserController } from '../controllers/UserController';

const router = express.Router();
const userController = new UserController();

router.get('/users', userController.list);
router.post('/users', userController.create);
router.get('/users/:id', userController.get);

export default router;

// ✅ 控制器层 - 请求/响应处理
// controllers/UserController.ts
import { Request, Response } from 'express';
import { UserService } from '../services/UserService';
import { CreateUserSchema } from '../schemas/user';

export class UserController {
  private userService = new UserService();

  list = async (req: Request, res: Response) => {
    try {
      const users = await this.userService.listUsers({
        page: parseInt(req.query.page as string) || 1,
        limit: parseInt(req.query.limit as string) || 20
      });
      res.json(users);
    } catch (error) {
      res.status(500).json({ error: '获取用户失败' });
    }
  };

  create = async (req: Request, res: Response) => {
    try {
      const validated = CreateUserSchema.parse(req.body);
      const user = await this.userService.createUser(validated);
      res.status(201).json(user);
    } catch (error) {
      res.status(400).json({ error: error.message });
    }
  };
}

// ✅ 服务层 - 业务逻辑
// services/UserService.ts
import { UserRepository } from '../repositories/UserRepository';
import { EmailService } from './EmailService';

export class UserService {
  private userRepo = new UserRepository();
  private emailService = new EmailService();

  async createUser(data: CreateUserInput) {
    // 业务逻辑在这里
    const existingUser = await this.userRepo.findByEmail(data.email);
    if (existingUser) {
      throw new Error('邮箱已存在');
    }

    const hashedPassword = await bcrypt.hash(data.password, 10);
    const user = await this.userRepo.create({
      ...data,
      passwordHash: hashedPassword
    });

    // 异步发送欢迎邮件
    await this.emailService.sendWelcome(user.email);

    return user;
  }

  async listUsers(params: { page: number; limit: number }) {
    return await this.userRepo.findMany({
      skip: (params.page - 1) * params.limit,
      take: params.limit
    });
  }
}

// ✅ 仓库层 - 数据访问
// repositories/UserRepository.ts
import { prisma } from '../db';

export class UserRepository {
  async create(data: CreateUserData) {
    return await prisma.user.create({ data });
  }

  async findByEmail(email: string) {
    return await prisma.user.findUnique({ where: { email } });
  }

  async findMany(params: { skip: number; take: number }) {
    return await prisma.user.findMany(params);
  }
}

2. 依赖注入

// ✅ 构造函数注入以提高可测试性
export class OrderService {
  constructor(
    private orderRepo: OrderRepository,
    private paymentService: PaymentService,
    private emailService: EmailService
  ) {}

  async processOrder(orderId: string) {
    const order = await this.orderRepo.findById(orderId);
    const payment = await this.paymentService.charge(order);
    await this.emailService.sendReceipt(order, payment);
    return payment;
  }
}

// 易于在测试中模拟
const mockOrderRepo = {
  findById: jest.fn().mockResolvedValue({ id: '1', total: 100 })
};
const mockPaymentService = {
  charge: jest.fn().mockResolvedValue({ id: 'pay_123' })
};
const service = new OrderService(mockOrderRepo, mockPaymentService, mockEmailService);

设计模式

1. 仓库模式

// ✅ 通过接口抽象数据访问
interface IUserRepository {
  create(data: CreateUserData): Promise<User>;
  findById(id: string): Promise<User | null>;
  update(id: string, data: UpdateUserData): Promise<User>;
  delete(id: string): Promise<void>;
}

// PostgreSQL实现
export class PostgresUserRepository implements IUserRepository {
  async create(data: CreateUserData) {
    return await prisma.user.create({ data });
  }
  
  async findById(id: string) {
    return await prisma.user.findUnique({ where: { id } });
  }
  
  // ... 其他方法
}

// MongoDB实现(易于替换)
export class MongoUserRepository implements IUserRepository {
  async create(data: CreateUserData) {
    return await User.create(data);
  }
  
  // ... 其他方法
}

2. 服务层模式

// ✅ 封装业务逻辑
export class OrderService {
  async placeOrder(userId: string, items: OrderItem[]) {
    // 验证库存
    for (const item of items) {
      const product = await this.productRepo.findById(item.productId);
      if (product.stock < item.quantity) {
        throw new InsufficientStockError(item.productId);
      }
    }

    // 计算总额
    const total = items.reduce((sum, item) => sum + item.price * item.quantity, 0);

    // 应用折扣
    const discount = await this.discountService.calculateDiscount(userId, total);

    // 创建订单
    const order = await this.orderRepo.create({
      userId,
      items,
      subtotal: total,
      discount,
      total: total - discount,
      status: 'pending'
    });

    // 保留库存
    for (const item of items) {
      await this.inventoryService.reserve(item.productId, item.quantity);
    }

    // 队列支付处理
    await this.paymentQueue.add({ orderId: order.id });

    return order;
  }
}

3. 工厂模式

// ✅ 基于条件创建对象
interface PaymentProvider {
  charge(amount: number, currency: string): Promise<PaymentResult>;
}

class StripeProvider implements PaymentProvider {
  async charge(amount: number, currency: string) {
    return await stripe.charges.create({ amount, currency });
  }
}

class PayPalProvider implements PaymentProvider {
  async charge(amount: number, currency: string) {
    return await paypal.payment.create({ amount, currency });
  }
}

class PaymentProviderFactory {
  static create(provider: string): PaymentProvider {
    switch (provider) {
      case 'stripe':
        return new StripeProvider();
      case 'paypal':
        return new PayPalProvider();
      default:
        throw new Error(`未知提供者: ${provider}`);
    }
  }
}

// 使用
const provider = PaymentProviderFactory.create(user.preferredPaymentMethod);
await provider.charge(100, 'USD');

4. 策略模式

// ✅ 在运行时交换算法
interface ShippingStrategy {
  calculateCost(weight: number, distance: number): number;
}

class StandardShipping implements ShippingStrategy {
  calculateCost(weight: number, distance: number) {
    return weight * 0.5 + distance * 0.1;
  }
}

class ExpressShipping implements ShippingStrategy {
  calculateCost(weight: number, distance: number) {
    return weight * 1.0 + distance * 0.3;
  }
}

class OvernightShipping implements ShippingStrategy {
  calculateCost(weight: number, distance: number) {
    return weight * 2.0 + distance * 0.5;
  }
}

class ShippingCalculator {
  constructor(private strategy: ShippingStrategy) {}

  calculate(weight: number, distance: number) {
    return this.strategy.calculateCost(weight, distance);
  }
}

// 使用
const calculator = new ShippingCalculator(new ExpressShipping());
const cost = calculator.calculate(10, 500);

5. 观察者模式(事件驱动)

// ✅ 通过事件解耦组件
import { EventEmitter } from 'events';

class OrderEvents extends EventEmitter {
  static CREATED = 'order.created';
  static PAID = 'order.paid';
  static SHIPPED = 'order.shipped';
  static CANCELLED = 'order.cancelled';
}

const orderEvents = new OrderEvents();

// 监听器
orderEvents.on(OrderEvents.CREATED, async (order) => {
  await emailService.sendOrderConfirmation(order);
  await analyticsService.trackOrderCreated(order);
});

orderEvents.on(OrderEvents.PAID, async (order) => {
  await inventoryService.deductStock(order.items);
  await shippingService.createShipment(order);
});

// 发射事件
export class OrderService {
  async createOrder(data: CreateOrderData) {
    const order = await this.orderRepo.create(data);
    orderEvents.emit(OrderEvents.CREATED, order);
    return order;
  }

  async markAsPaid(orderId: string) {
    const order = await this.orderRepo.update(orderId, { status: 'paid' });
    orderEvents.emit(OrderEvents.PAID, order);
    return order;
  }
}

微服务模式

1. API网关

// ✅ 多个服务的单一入口点
import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';

const app = express();

// 路由到不同服务
app.use('/api/users', createProxyMiddleware({ 
  target: 'http://user-service:3001',
  changeOrigin: true 
}));

app.use('/api/orders', createProxyMiddleware({ 
  target: 'http://order-service:3002',
  changeOrigin: true 
}));

app.use('/api/payments', createProxyMiddleware({ 
  target: 'http://payment-service:3003',
  changeOrigin: true 
}));

// 在此处添加认证、速率限制、日志
app.use(authMiddleware);
app.use(rateLimiter);
app.use(logger);

2. 服务间通信

// ✅ HTTP/REST通信
export class UserService {
  private orderServiceUrl = process.env.ORDER_SERVICE_URL;

  async getUserWithOrders(userId: string) {
    const user = await this.userRepo.findById(userId);
    
    // 调用订单服务
    const response = await fetch(`${this.orderServiceUrl}/orders?userId=${userId}`);
    const orders = await response.json();

    return { ...user, orders };
  }
}

// ✅ 消息队列通信(异步)
import { Queue } from 'bullmq';

const emailQueue = new Queue('emails', {
  connection: { host: 'redis', port: 6379 }
});

// 生产者(用户服务)
export class UserService {
  async createUser(data: CreateUserData) {
    const user = await this.userRepo.create(data);
    
    // 异步通知
    await emailQueue.add('welcome', {
      userId: user.id,
      email: user.email
    });

    return user;
  }
}

// 消费者(邮件服务)
import { Worker } from 'bullmq';

const worker = new Worker('emails', async (job) => {
  if (job.name === 'welcome') {
    await sendWelcomeEmail(job.data.email);
  }
});

3. 断路器模式

// ✅ 防止级联故障
import CircuitBreaker from 'opossum';

const options = {
  timeout: 3000,        // 如果函数耗时 > 3秒,触发失败
  errorThresholdPercentage: 50,  // 当50%请求失败时...
  resetTimeout: 30000   // ...打开电路30秒
};

const breaker = new CircuitBreaker(callExternalAPI, options);

breaker.fallback(() => {
  return { data: null, fromCache: true }; // 回退响应
});

breaker.on('open', () => {
  console.log('断路器打开 - 太多失败');
});

async function callExternalAPI() {
  const response = await fetch('https://external-api.com/data');
  return response.json();
}

// 使用
try {
  const data = await breaker.fire();
} catch (error) {
  // 电路打开或请求失败
}

Serverless模式

1. 函数即服务

// ✅ AWS Lambda处理器
import { APIGatewayProxyHandler } from 'aws-lambda';

export const handler: APIGatewayProxyHandler = async (event) => {
  try {
    const body = JSON.parse(event.body || '{}');
    
    // 业务逻辑
    const result = await processOrder(body);

    return {
      statusCode: 200,
      headers: {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*'
      },
      body: JSON.stringify(result)
    };
  } catch (error) {
    return {
      statusCode: 500,
      body: JSON.stringify({ error: error.message })
    };
  }
};

// ✅ Vercel Edge函数
export const config = {
  runtime: 'edge'
};

export default async function handler(request: Request) {
  const data = await processData();
  
  return new Response(JSON.stringify(data), {
    headers: { 'content-type': 'application/json' }
  });
}

2. 冷启动优化

// ✅ 在处理器外初始化(跨调用持久化)
import { PrismaClient } from '@prisma/client';

// 创建一次,在热调用中重用
const prisma = new PrismaClient();

export const handler = async (event) => {
  // 每次调用运行
  const users = await prisma.user.findMany();
  return { statusCode: 200, body: JSON.stringify(users) };
};

// ✅ 懒初始化
let connection: Connection | null = null;

async function getConnection() {
  if (!connection) {
    connection = await createConnection();
  }
  return connection;
}

export const handler = async (event) => {
  const conn = await getConnection();
  // 使用连接
};

后台作业

1. 作业队列模式

// ✅ BullMQ作业处理
import { Queue, Worker } from 'bullmq';

const videoQueue = new Queue('video-processing', {
  connection: { host: 'redis', port: 6379 }
});

// 添加作业
export class VideoService {
  async uploadVideo(file: File) {
    const video = await this.videoRepo.create({ 
      filename: file.name,
      status: 'pending'
    });

    // 队列处理作业
    await videoQueue.add('transcode', {
      videoId: video.id,
      inputPath: file.path
    }, {
      attempts: 3,           // 重试最多3次
      backoff: {
        type: 'exponential',
        delay: 5000          // 5秒,10秒,20秒
      }
    });

    return video;
  }
}

// 工作进程
const worker = new Worker('video-processing', async (job) => {
  if (job.name === 'transcode') {
    await transcodeVideo(job.data.videoId, job.data.inputPath);
    
    // 更新进度
    job.updateProgress(50);
    
    await generateThumbnail(job.data.videoId);
    
    job.updateProgress(100);
  }
}, {
  connection: { host: 'redis', port: 6379 },
  concurrency: 5  // 并发处理5个作业
});

worker.on('completed', (job) => {
  console.log(`作业 ${job.id} 完成`);
});

worker.on('failed', (job, err) => {
  console.error(`作业 ${job.id} 失败:`, err);
});

2. 定时任务

// ✅ 使用node-cron的Cron作业
import cron from 'node-cron';

// 每天午夜运行
cron.schedule('0 0 * * *', async () => {
  await cleanupExpiredSessions();
  await generateDailyReport();
});

// 每5分钟运行
cron.schedule('*/5 * * * *', async () => {
  await checkPaymentStatus();
});

// ✅ 或使用BullMQ重复
await queue.add('daily-report', {}, {
  repeat: {
    pattern: '0 0 * * *'  // Cron表达式
  }
});

后端最佳实践

1. 配置管理

// ✅ 基于环境的配置
export const config = {
  port: parseInt(process.env.PORT || '3000'),
  database: {
    url: process.env.DATABASE_URL,
    poolSize: parseInt(process.env.DB_POOL_SIZE || '10')
  },
  redis: {
    host: process.env.REDIS_HOST || 'localhost',
    port: parseInt(process.env.REDIS_PORT || '6379')
  },
  jwt: {
    secret: process.env.JWT_SECRET,
    expiresIn: '1h'
  }
};

// 在启动时验证必需变量
const required = ['DATABASE_URL', 'JWT_SECRET'];
for (const key of required) {
  if (!process.env[key]) {
    throw new Error(`缺少必需环境变量: ${key}`);
  }
}

2. 健康检查

// ✅ 健康检查端点
app.get('/health', async (req, res) => {
  const health = {
    uptime: process.uptime(),
    timestamp: Date.now(),
    status: 'ok',
    checks: {
      database: 'ok',
      redis: 'ok'
    }
  };

  try {
    await prisma.$queryRaw`SELECT 1`;
  } catch (error) {
    health.status = 'degraded';
    health.checks.database = 'error';
  }

  try {
    await redis.ping();
  } catch (error) {
    health.status = 'degraded';
    health.checks.redis = 'error';
  }

  const statusCode = health.status === 'ok' ? 200 : 503;
  res.status(statusCode).json(health);
});

后端服务检查清单

架构:
□ 清晰的关注点分离(路由/控制器/服务/仓库)
□ 依赖注入以提高可测试性
□ 业务逻辑在服务层(不在控制器中)
□ 数据访问抽象在仓库中
□ 控制器中无数据库查询

API设计:
□ RESTful端点
□ 适当的HTTP方法和状态码
□ 所有端点的输入验证
□ 列表分页
□ API版本控制策略

错误处理:
□ 所有异步函数中的try/catch
□ 有意义的错误消息
□ 适当的错误状态码
□ 带上下文的错误日志
□ 错误响应中无敏感数据

性能:
□ 数据库查询优化
□ 连接池配置
□ 缓存策略实现
□ 繁重操作用后台作业
□ 公共端点的速率限制

安全:
□ 需要认证
□ 授权检查
□ 输入净化
□ SQL注入预防
□ CORS正确配置

监控:
□ 健康检查端点
□ 日志配置
□ 指标收集
□ 错误跟踪(Sentry等)
□ 性能监控

资源


记住:优秀的后端服务是可维护、可测试、可扩展和弹性的。为失败设计,为可读性优化。