CodeBuddy + Node.js 后端API完整开发指南
可直接丢给CodeBuddy生成、迭代调试的工程规范、目录结构、提示词模板,以及基础Node.js后端模板代码(Express)。 你复制提示词发给CodeBuddy,它就能一键生成项目、路由、参数校验、错误处理、CRUD接口。
摘要:本文提供一套可直接丢给 CodeBuddy 使用的 Node.js 后端 API 开发方案,涵盖技术选型、标准目录结构、三段可直接复制的提示词模板,以及完整的 Express 基础模板代码(含统一返回、MySQL 连接池、zod 校验、全局异常捕获、用户 CRUD 示例)。最后给出从生成骨架到对接前端的六步实操工作流,帮助你用 CodeBuddy 快速搭建、迭代并交付后端接口。
一、技术选型(固定给CodeBuddy)
- 运行环境:Node.js 20+
- Web框架:Express
- 数据库:MySQL2(如果你用PostgreSQL换成pg)
- 参数校验:zod
- 跨域:cors
- 日志:morgan
- 环境变量:dotenv
- 项目规范:RESTful API,统一返回格式,全局异常捕获,分页封装,不使用ORM,原生SQL
二、标准目录结构(直接发给CodeBuddy)
node-api/
├── .env #环境变量
├── package.json
├── src
│ ├── app.js #入口,中间件、全局异常、cors
│ ├── config
│ │ └── db.js #mysql连接池
│ ├── controller #控制器,业务逻辑
│ │ └── userController.js
│ ├── router #路由定义
│ │ └── userRouter.js
│ ├── middleware
│ │ ├── errorHandler.js #全局错误中间件
│ │ └── validate.js #zod校验中间件
│ ├── schema #zod参数校验规则
│ │ └── userSchema.js
│ └── utils
│ └── response.js #统一返回封装
└── README.md
三、【直接复制给CodeBuddy的提示词模板】
模板1:新建完整后端骨架
请基于Express搭建Node.js后端RESTful API项目,严格使用下面目录结构:
src/app.js、config/db.js、controller、router、middleware、schema、utils
技术栈:node20,express,cors,morgan,dotenv,zod,mysql2连接池
要求:
1、utils/response.js实现统一返回体{code,msg,data},code=200成功,500服务错误,400参数错误
2、middleware/errorHandler全局捕获异常,不要trycatch散在controller里
3、middleware/validate.js封装zod校验,路由中使用
4、db.js创建mysql连接池,从.env读取配置
5、实现user模块CRUD接口:分页列表、根据id查询、新增、编辑、删除
6、所有接口增加zod参数校验,分页默认page=1,size=10
7、代码增加注释,不要sequelize等ORM,使用mysql2原生sql
8、生成package.json、.env模板,给出启动步骤
模板2:新增一个业务模块(比如客户CRM导入CSV接口,贴合你之前Qt项目)
在现有Express项目新增customer客户模块:
1、新建controller/customerController.js、router/customerRouter.js、schema/customerSchema.js
2、提供接口:
GET /api/customer/list 分页查询客户列表
POST /api/customer/batchImport 批量导入接口,接收json数组多条客户数据
GET /api/customer/:id 获取单条
POST /api/customer/add新增
PUT /api/customer/:id编辑
DELETE /api/customer/:id删除
3、所有入参使用zod校验,统一返回格式,数据库使用mysql2原生SQL
4、路由注册到app.js,增加详细注释
模板3:让CodeBuddy排查bug/优化接口
下面是我的xxx接口代码,存在【描述问题:例如大批量导入性能差、没有事务、未做参数过滤】
请优化代码:
1、增加mysql事务,出错回滚
2、增加批量插入优化,避免循环单条insert
3、增加参数过滤,防止sql注入
4、增加日志打印,捕获数据库异常交给全局异常中间件
贴代码:
【粘贴你的js代码】
四、基础模板代码(可以直接作为初始代码喂给CodeBuddy迭代)
1. package.json
json
{
"name": "node-api",
"version": "1.0.0",
"main": "src/app.js",
"scripts": {
"dev": "node src/app.js"
},
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"morgan": "^1.10.0",
"mysql2": "^3.11.0",
"zod": "^3.23.8"
}
}
2. .env
js
PORT=3000
DB_HOST=127.0.0.1
DB_USER=root
DB_PASS=123456
DB_NAME=crm_db
DB_PORT=3306
3. src/utils/response.js(统一返回)
js
//成功返回
const success = (data, msg = 'ok') => {
return { code: 200, msg, data }
}
//失败返回
const fail = (msg = 'error', code = 400) => {
return { code, msg, data: null }
}
module.exports = { success, fail }
4.src/config/db.js MySQL连接池
js
require('dotenv').config()
const mysql = require('mysql2/promise')
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
port: process.env.DB_PORT,
waitForConnections: true,
connectionLimit: 10
})
module.exports = pool
5.src/middleware/validate.js zod校验中间件
js
const { fail } = require('../utils/response')
const validate = (schema) => (req, res, next) => {
const result = schema.safeParse({
...req.body,
...req.query,
...req.params
})
if (!result.success) {
const errMsg = result.error.issues.map(i=>i.message).join(',')
return res.json(fail(errMsg,400))
}
next()
}
module.exports = validate
6.src/middleware/errorHandler.js全局异常捕获
js
const { fail } = require('../utils/response')
const errorHandler = (err,req,res,next)=>{
console.error(err)
res.json(fail('服务器内部错误',500))
}
module.exports = errorHandler
7.src/app.js入口文件
js
require('dotenv').config()
const express = require('express')
const cors = require('cors')
const morgan = require('morgan')
const errorHandler = require('./middleware/errorHandler')
const userRouter = require('./router/userRouter')
const app = express()
const PORT = process.env.PORT || 3000
app.use(cors())
app.use(morgan('dev'))
app.use(express.json())
//注册路由
app.use('/api/user',userRouter)
//全局异常中间件,必须放在最后
app.use(errorHandler)
app.listen(PORT,()=>{
console.log(`server run at http://127.0.0.1:${PORT}`)
})
8.示例模块:schema/userSchema.js
js
const {z}=require('zod')
const pageSchema = z.object({
page:z.coerce.number().int().min(1).default(1),
size:z.coerce.number().int().min(1).max(100).default(10)
})
const idSchema=z.object({
id:z.coerce.number().int().min(1)
})
const userCreateSchema=z.object({
username:z.string().min(2),
phone:z.string()
})
module.exports={pageSchema,idSchema,userCreateSchema}
9.router/userRouter.js
js
const express=require('express')
const router=express.Router()
const controller=require('../controller/userController')
const validate=require('../middleware/validate')
const {pageSchema,idSchema,userCreateSchema}=require('../schema/userSchema')
router.get('/list',validate(pageSchema),controller.getUserList)
router.get('/:id',validate(idSchema),controller.getUserById)
router.post('/add',validate(userCreateSchema),controller.addUser)
module.exports=router
10.controller/userController.js
js
const pool=require('../config/db')
const {success}=require('../utils/response')
exports.getUserList=async(req,res,next)=>{
try{
const {page,size}=req.query
const offset=(page-1)*size
const [rows]=await pool.query('select * from user limit ?,?',[offset,size])
const [totalRow]=await pool.query('select count(1) total from user')
const total=totalRow[0].total
res.json(success({list:rows,total,page,size}))
}catch(e){next(e)}
}
exports.getUserById=async(req,res,next)=>{
try{
const {id}=req.params
const [row]=await pool.query('select * from user where id=?',[id])
res.json(success(row[0]||null))
}catch(e){next(e)}
}
exports.addUser=async(req,res,next)=>{
try{
const {username,phone}=req.body
await pool.query('insert into user(username,phone) values(?,?)',[username,phone])
res.json(success(null,'新增成功'))
}catch(e){next(e)}
}
五、CodeBuddy开发工作流(实操步骤)
- 第一步:发送长提示词,让CodeBuddy生成整套项目骨架
- 第二步:运行npm i安装依赖,启动npm run dev,测试基础接口
- 第三步:新增业务模块,复制模块提示词,让它追加controller/router/schema
- 第四步:遇到BUG,直接粘贴报错+代码,让CodeBuddy定位修复
- 第五步:性能/安全优化,发送优化提示词,增加事务、批量插入、防SQL注入、接口限流、JWT登录鉴权
- 第六步:对接前端/Qt客户端,生成接口文档(让CodeBuddy输出Markdown接口文档)