温馨提示×

Node.js在Linux上的API接口如何设计

小樊
35
2025-12-06 13:10:51
栏目: 编程语言

Node.js 在 Linux 上的 API 接口设计指南

一 设计原则与规范

  • 采用RESTful风格:以资源为中心,使用HTTP 方法表达语义,URI 使用名词复数,通过路径参数标识资源实例,如:GET /users/{id}
  • 保持无状态:每次请求携带完成处理所需的全部信息,便于水平扩展与缓存。
  • 统一版本控制:将版本放入路径,如:/v1/users,避免破坏性变更影响现有客户端。
  • 正确使用HTTP 状态码:如创建成功返回201 Created,参数错误400 Bad Request,未找到404 Not Found,服务器错误500 Internal Server Error
  • 善用HTTP 头传递元数据:如分页、速率限制、内容协商;自定义头建议使用前缀避免冲突,并注意 Node.js 对请求头总大小约 80KB的限制。
  • 采用设计优先(Design-First):先以 OpenAPI/Swagger 定义契约,再编码实现,保证文档与实现一致、团队协作顺畅。

二 路由与响应设计

  • 路由命名与 HTTP 方法映射(示例):
    动作 方法 URI 成功状态码
    获取列表 GET /v1/users 200 OK
    创建 POST /v1/users 201 Created
    获取单个 GET /v1/users/{id} 200 OK
    全量更新 PUT /v1/users/{id} 200 OK
    部分更新 PATCH /v1/users/{id} 200 OK
    删除 DELETE /v1/users/{id} 204 No Content
  • 请求与响应约定:
    • 请求体使用JSON,设置 Content-Type: application/json
    • 响应体统一结构,如:
      • 成功:{ “data”: …, “meta”: { “page”: 1, “limit”: 20 } }
      • 失败:{ “error”: { “code”: “InvalidInput”, “message”: “…” } }
    • 支持条件请求(如 ETag/If-None-Match)提升缓存命中与性能。
    • 分页、排序、过滤通过查询参数实现,如:/v1/users?page=2&limit=50&sort=name:asc。

三 安全与 Linux 运行时防护

  • 传输与边界安全:全站启用HTTPS;在 Nginx/Apache 终止 TLS 并反向代理到 Node.js(如 3000 端口);合理配置 CORS 仅允许受信源;使用 Helmet 设置安全响应头。
  • 敏感信息与依赖:用环境变量管理密钥(如 dotenv);定期执行 npm audit fix、升级 Node.js 与依赖;避免 eval、限制全局变量、审查第三方库。
  • 访问控制与网络:仅开放必要端口(如 22/80/443),使用 ufw 或云安全组限制来源;为 API 增加限流认证(如 JWT)策略。
  • 运行与权限:使用非 root用户运行服务;最小权限原则;启用进程守护(如 systemd)与日志轮转

四 文档与可观测性

  • 文档:采用设计优先,以 OpenAPI 3.0 维护契约;在项目中集成 Swagger UI(如 swagger-ui-express)提供交互式文档与在线调试。
  • 日志与监控:使用 Morgan 记录访问日志,结构化输出便于检索;使用 Winston 记录业务与错误日志;完善指标与链路追踪,便于故障定位与容量规划。

五 最小可行示例 Express 代码

  • 目录结构
    • project/
      • src/
        • routes/
          • users.js
        • controllers/
          • users.js
        • middleware/
          • validation.js
        • app.js
        • server.js
      • openapi.yaml
      • package.json
  • 关键代码
    • package.json(节选)
      • “dependencies”: { “express”: “^4.18”, “helmet”: “^7”, “cors”: “^2”, “morgan”: “^1”, “dotenv”: “^16”, “swagger-ui-express”: “^5”, “express-validator”: “^7” }
    • src/app.js
      • const express = require(‘express’); const helmet = require(‘helmet’); const cors = require(‘cors’); const morgan = require(‘morgan’); const { body, validationResult } = require(‘express-validator’); const usersRouter = require(‘./routes/users’);

        const app = express(); app.use(helmet()); app.use(cors({ origin: process.env.CORS_ORIGIN?.split(‘,’) || ‘*’ })); app.use(morgan(‘combined’)); app.use(express.json({ limit: ‘10kb’ }));

        // 统一错误处理 app.use((err, req, res, next) => { const status = err.status || 500; res.status(status).json({ error: { code: err.code || ‘InternalError’, message: err.message } }); });

        app.use(‘/v1/users’, usersRouter); module.exports = app;

    • src/controllers/users.js
      • const createUser = (req, res, next) => { const errors = validationResult(req); if (!errors.isEmpty()) return res.status(400).json({ error: { code: ‘InvalidInput’, message: errors.array()[0].msg } }); // TODO: 业务创建逻辑 const user = { id: Date.now(), …req.body }; res.status(201).json({ data: user }); };

        const getUser = (req, res) => { const { id } = req.params; // TODO: 业务查询逻辑 res.json({ data: { id: Number(id), name: ‘Demo’ } }); };

        module.exports = { createUser, getUser };

    • src/routes/users.js
      • const express = require(‘express’); const router = express.Router(); const { body, param } = require(‘express-validator’); const { createUser, getUser } = require(‘…/controllers/users’);

        router.post(‘/’, body(‘email’).isEmail().withMessage(‘Invalid email’), body(‘name’).isLength({ min: 1 }).withMessage(‘Name required’), createUser ); router.get(‘/:id’, param(‘id’).isInt().withMessage(‘ID must be integer’), getUser);

        module.exports = router;

    • src/server.js
      • const app = require(‘./app’); const port = process.env.PORT || 3000; app.listen(port, () => console.log(API listening on ${port}));
    • 快速启动
      • npm i
      • 配置 .env:PORT=3000 CORS_ORIGIN=https://yourdomain.com
      • node src/server.js
      • 建议同时维护 openapi.yaml 并用 swagger-ui-express 暴露 /docs 页面

0