Express.jsAPI开发技能 express

本技能提供基于Node.js的Express.js框架的API开发专家指导,涵盖中间件配置、RESTful路由设计、错误处理、安全防护、数据验证及生产环境部署等核心实践。关键词:Express.js, Node.js API, 后端开发, RESTful, 中间件, 错误处理, 安全最佳实践, 生产部署。

后端开发 0 次安装 0 次浏览 更新于 2/26/2026

name: express description: Express.js 中间件模式、路由、错误处理、安全性和生产环境最佳实践。 allowed-tools: Read, Write, Edit, Bash, Glob, Grep

Express 技能

使用 Express.js 构建 Node.js API 的专家级协助。

能力

  • 使用中间件配置 Express 应用程序
  • 实现 RESTful 路由模式
  • 使用自定义中间件处理错误
  • 应用安全最佳实践
  • 设置验证和解析
  • 配置生产环境部署

用法

当您需要时,请调用此技能:

  • 使用 Express 构建 REST API
  • 实现中间件管道
  • 优雅地处理错误
  • 添加身份验证/授权
  • 设置 API 文档

输入

参数 类型 是否必需 描述
routePath 字符串 路由路径前缀
methods 数组 HTTP 方法
middleware 数组 要应用的中间件
validation 布尔值 添加验证

模式

应用程序设置

// src/app.ts
import express, { Express, Request, Response, NextFunction } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import compression from 'compression';
import morgan from 'morgan';
import { rateLimit } from 'express-rate-limit';

import { errorHandler, notFoundHandler } from './middleware/error';
import { usersRouter } from './routes/users';
import { authRouter } from './routes/auth';

export function createApp(): Express {
  const app = express();

  // 安全中间件
  app.use(helmet());
  app.use(cors({
    origin: process.env.CORS_ORIGIN || 'http://localhost:3000',
    credentials: true,
  }));

  // 速率限制
  app.use(rateLimit({
    windowMs: 15 * 60 * 1000,
    max: 100,
    standardHeaders: true,
    legacyHeaders: false,
  }));

  // 解析
  app.use(express.json({ limit: '10kb' }));
  app.use(express.urlencoded({ extended: true, limit: '10kb' }));

  // 压缩和日志记录
  app.use(compression());
  app.use(morgan(process.env.NODE_ENV === 'production' ? 'combined' : 'dev'));

  // 路由
  app.use('/api/auth', authRouter);
  app.use('/api/users', usersRouter);

  // 健康检查
  app.get('/health', (req, res) => {
    res.json({ status: 'ok', timestamp: new Date().toISOString() });
  });

  // 错误处理
  app.use(notFoundHandler);
  app.use(errorHandler);

  return app;
}

带控制器的路由器

// src/routes/users.ts
import { Router } from 'express';
import { UsersController } from '../controllers/users.controller';
import { authenticate, authorize } from '../middleware/auth';
import { validate } from '../middleware/validate';
import { createUserSchema, updateUserSchema } from '../schemas/user.schema';

const router = Router();
const controller = new UsersController();

router.get('/', authenticate, controller.findAll);
router.get('/:id', authenticate, controller.findById);
router.post('/', authenticate, authorize('admin'), validate(createUserSchema), controller.create);
router.put('/:id', authenticate, validate(updateUserSchema), controller.update);
router.delete('/:id', authenticate, authorize('admin'), controller.delete);

export { router as usersRouter };

// src/controllers/users.controller.ts
import { Request, Response, NextFunction } from 'express';
import { UsersService } from '../services/users.service';

export class UsersController {
  private service = new UsersService();

  findAll = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const { page = 1, limit = 10, search } = req.query;
      const users = await this.service.findAll({
        page: Number(page),
        limit: Number(limit),
        search: search as string,
      });
      res.json(users);
    } catch (error) {
      next(error);
    }
  };

  findById = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const user = await this.service.findById(req.params.id);
      if (!user) {
        return res.status(404).json({ error: '用户未找到' });
      }
      res.json(user);
    } catch (error) {
      next(error);
    }
  };

  create = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const user = await this.service.create(req.body);
      res.status(201).json(user);
    } catch (error) {
      next(error);
    }
  };

  update = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const user = await this.service.update(req.params.id, req.body);
      res.json(user);
    } catch (error) {
      next(error);
    }
  };

  delete = async (req: Request, res: Response, next: NextFunction) => {
    try {
      await this.service.delete(req.params.id);
      res.status(204).send();
    } catch (error) {
      next(error);
    }
  };
}

中间件模式

// src/middleware/auth.ts
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';

export interface AuthRequest extends Request {
  user?: {
    id: string;
    email: string;
    role: string;
  };
}

export function authenticate(req: AuthRequest, res: Response, next: NextFunction) {
  const token = req.headers.authorization?.replace('Bearer ', '');

  if (!token) {
    return res.status(401).json({ error: '需要身份验证' });
  }

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET!) as AuthRequest['user'];
    req.user = decoded;
    next();
  } catch {
    return res.status(401).json({ error: '无效令牌' });
  }
}

export function authorize(...roles: string[]) {
  return (req: AuthRequest, res: Response, next: NextFunction) => {
    if (!req.user || !roles.includes(req.user.role)) {
      return res.status(403).json({ error: '权限不足' });
    }
    next();
  };
}

// src/middleware/validate.ts
import { Request, Response, NextFunction } from 'express';
import { ZodSchema, ZodError } from 'zod';

export function validate(schema: ZodSchema) {
  return (req: Request, res: Response, next: NextFunction) => {
    try {
      schema.parse(req.body);
      next();
    } catch (error) {
      if (error instanceof ZodError) {
        return res.status(400).json({
          error: '验证失败',
          details: error.errors,
        });
      }
      next(error);
    }
  };
}

// src/middleware/error.ts
import { Request, Response, NextFunction } from 'express';

export class AppError extends Error {
  constructor(
    public statusCode: number,
    public message: string,
    public isOperational = true
  ) {
    super(message);
  }
}

export function notFoundHandler(req: Request, res: Response) {
  res.status(404).json({ error: '未找到' });
}

export function errorHandler(
  err: Error,
  req: Request,
  res: Response,
  next: NextFunction
) {
  console.error(err);

  if (err instanceof AppError) {
    return res.status(err.statusCode).json({ error: err.message });
  }

  res.status(500).json({
    error: process.env.NODE_ENV === 'production'
      ? '内部服务器错误'
      : err.message,
  });
}

异步处理程序包装器

// src/utils/asyncHandler.ts
import { Request, Response, NextFunction, RequestHandler } from 'express';

type AsyncRequestHandler = (
  req: Request,
  res: Response,
  next: NextFunction
) => Promise<any>;

export function asyncHandler(fn: AsyncRequestHandler): RequestHandler {
  return (req, res, next) => {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
}

// 用法
router.get('/', asyncHandler(async (req, res) => {
  const users = await usersService.findAll();
  res.json(users);
}));

最佳实践

  • 使用中间件处理横切关注点
  • 实现适当的错误处理
  • 验证所有输入
  • 应用安全中间件(helmet、cors、速率限制)
  • 使用控制器和服务结构化代码

目标流程

  • nodejs-api-开发
  • rest-api-开发
  • mern-栈开发
  • 后端架构