You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Restify的REST API目录结构与样板代码咨询

我完全懂你这种感受——找个能直接复用、结构清晰的Restify样板确实不容易,毕竟大部分教程都停留在小demo层面。下面我分享一套我在实际项目里常用的结构,还有导入处理的最佳实践,应该能帮你理清思路:

一、推荐的Restify项目目录结构

这套结构遵循职责单一原则,把不同功能的代码拆分到对应目录,后期维护和扩展都很方便:

your-api/
├── src/
│   ├── config/          # 配置文件(数据库、环境变量、端口等)
│   │   ├── index.js
│   │   └── env/
│   │       ├── development.js
│   │       └── production.js
│   ├── controllers/     # 业务逻辑处理(对应每个资源的CRUD)
│   │   ├── user.controller.js
│   │   └── order.controller.js
│   ├── routes/          # 路由定义,把请求映射到控制器
│   │   ├── index.js
│   │   ├── user.routes.js
│   │   └── order.routes.js
│   ├── models/          # 数据模型(搭配ORM如Sequelize/Mongoose使用)
│   │   ├── User.js
│   │   └── Order.js
│   ├── middlewares/     # 自定义中间件(权限验证、日志、错误处理等)
│   │   ├── auth.middleware.js
│   │   └── error-handler.middleware.js
│   ├── services/        # 复用性业务服务(邮件发送、第三方API调用等)
│   │   ├── email.service.js
│   │   └── payment.service.js
│   ├── utils/           # 通用工具函数(格式化、验证、常量定义)
│   │   ├── validation.utils.js
│   │   └── constants.js
│   └── server.js        # 服务器入口,初始化Restify、加载路由和中间件
├── package.json
├── .env                # 环境变量(不要提交到Git)
└── .gitignore

简单解释下各目录的作用:

  • config/:集中管理不同环境的配置,比如开发环境用本地数据库,生产环境用云数据库
  • controllers/:直接处理请求和响应,调用services完成业务逻辑,不直接操作数据库
  • routes/:只负责定义URL和HTTP方法,把请求转发给对应的控制器方法
  • middlewares/:处理请求前后的通用逻辑,比如验证用户登录状态、记录请求日志
  • services/:抽离可复用的业务逻辑,比如发送验证码、生成订单,让控制器更简洁
二、导入处理的最佳实践

Restify默认支持CommonJS,但现在很多项目也会用ES Modules,两种方案的处理方式如下:

1. 使用CommonJS(Restify默认)

如果你的项目用require()和module.exports,可以通过模块别名解决相对路径过长的问题:

  • 安装module-alias包:npm install module-alias
  • 在package.json里添加别名配置:
    "_moduleAliases": {
      "@config": "./src/config",
      "@controllers": "./src/controllers",
      "@routes": "./src/routes"
    }
    
  • 在server.js顶部注册别名:
    require('module-alias/register');
    

之后就可以这样导入,不用再写冗长的../:

const config = require('@config');
const userController = require('@controllers/user.controller');

2. 使用ES Modules(现代方式)

如果想改用import/export,先在package.json里设置"type": "module",然后:

  • 导入路径必须加.js后缀(比如import { getUser } from '../controllers/user.controller.js')
  • 同样可以用别名,在package.json里配置:
    "imports": {
      "#config/*": "./src/config/*",
      "#controllers/*": "./src/controllers/*"
    }
    

之后导入就会更简洁:

import config from '#config/index.js';
import { getUser } from '#controllers/user.controller.js';
三、快速启动的核心代码示例

基于上面的结构,你可以快速写出基础的启动代码:

  • server.js(服务器入口):
    const restify = require('restify');
    const routes = require('./routes');
    const errorHandler = require('./middlewares/error-handler.middleware');
    
    const server = restify.createServer({
      name: 'your-api',
      version: '1.0.0'
    });
    
    // 注册Restify自带的通用中间件
    server.use(restify.plugins.acceptParser(server.acceptable));
    server.use(restify.plugins.queryParser());
    server.use(restify.plugins.bodyParser());
    
    // 加载所有路由
    routes(server);
    
    // 全局错误处理
    server.on('restifyError', errorHandler);
    
    const PORT = process.env.PORT || 3000;
    server.listen(PORT, () => {
      console.log('%s listening at %s', server.name, server.url);
    });
    
  • routes/index.js(统一注册路由):
    const userRoutes = require('./user.routes');
    
    module.exports = (server) => {
      userRoutes(server);
      // 后续添加其他路由,比如orderRoutes(server)
    };
    
  • user.routes.js(用户资源路由):
    const { getUser, createUser } = require('../controllers/user.controller');
    
    module.exports = (server) => {
      server.get('/users/:id', getUser);
      server.post('/users', createUser);
    };
    

这种结构的好处是职责清晰,每个模块只做一件事,哪怕后期项目变大,也能轻松扩展新的资源或功能。你可以根据自己的项目规模调整,比如小项目可以把services和utils合并,或者不用models(如果直接操作SQL而不用ORM)。

内容的提问来源于stack exchange,提问作者Circle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:48:58