【Node.js】实战:从 0 搭建一个任务管理 RESTful API(Node 22 + Express)】
从零搭建一个 Node.js 22 Express 的任务管理 RESTful API涵盖环境搭建、项目结构、路由设计、CRUD 实战、错误处理和测试。每个关键步骤都配图 可跑代码适合直接照着敲一遍然后发到 CSDN 当成自己的 Node.js 实战博文。目录一、为什么 2025 年还值得学 Node.js 实战二、实战目标我们要搭什么三、整体流程一眼看完四、环境准备与项目初始化1. 确认 Node.js 版本推荐 22 LTS2. 初始化项目3. 安装依赖五、项目结构按“功能模块”组织六、写入口app.js七、写路由routes/tasks.js核心 CRUD八、跑起来 用 curl 测试1. 启动服务器2. 测试 CRUD九、加点“工程味”错误处理 输入校验1. 统一错误响应中间件2. 更严格的参数校验十、避坑指南新手最容易踩的坑十一、如何把这篇变成你自己的 CSDN 博文一、为什么 2025 年还值得学 Node.js 实战Node.js 22 已经进入 LTS原生支持 TypeScript 执行、内置 WebSocket 客户端、require(esm)、.env文件等很多以前必须装包才能干的事现在运行时自己就能搞定mortexsolutions.com。Express 依然是 2025 年最主流的 Node.js Web 框架之一生态成熟、资料最多jeuxdevelopers.com1。RESTful API 仍然是后端最基础的“通用语言”学会用 Node.js 搭一套 API以后不管是接前端、写管理后台还是做微服务都很有用jianshu.com。二、实战目标我们要搭什么我们要做一个“任务管理系统Tasks API”功能包括获取所有任务GET /tasks获取单个任务GET /tasks/:id创建新任务POST /tasks更新任务PUT /tasks/:id删除任务DELETE /tasks/:id数据先放内存数组不连数据库方便专注理解 Node Express 本身。三、整体流程一眼看完四、环境准备与项目初始化1. 确认 Node.js 版本推荐 22 LTSnode -v # 建议看到 v22.x.x如果版本太旧去官网下载 22 LTS 安装aliyun.com。2. 初始化项目mkdir node-task-api cd node-task-api npm init -y这会生成一个package.json记录项目信息和依赖aliyun.com。3. 安装依赖npm install express npm install --save-dev nodemonexpressWeb 框架用来定义路由和中间件aliyun.com。nodemon开发时自动重启服务改完代码不用自己CtrlC再启动aliyun.com。在package.json的scripts里加一条scripts: { start: nodemon app.js }以后只需要npm start就能跑开发服务器。五、项目结构按“功能模块”组织2025 年比较推荐的 Node.js 项目结构是按功能分层而不是所有代码塞进一个文件logrocket.com2。我们这次用一个简化版结构node-task-api/ ├── app.js # 入口创建 Express 应用加载路由 ├── package.json ├── package-lock.json └── routes/ └── tasks.js # 任务相关路由 秘籍随着项目变大你还可以再加controllers、services、models等目录把“路由 / 业务逻辑 / 数据访问”分层dev.to。六、写入口app.js// app.js const express require(express); const tasksRoutes require(./routes/tasks); const app express(); const PORT process.env.PORT || 3000; // 1. 中间件解析 JSON 请求体 app.use(express.json()); // 2. 简单日志中间件自己写 app.use((req, res, next) { const start Date.now(); res.on(finish, () { const cost Date.now() - start; console.log(${req.method}${req.url} - ${res.statusCode} -${cost}ms); }); next(); }); // 3. 路由/tasks 下的所有接口 app.use(/tasks, tasksRoutes); // 4. 启动服务器 app.listen(PORT, () { console.log(Server is running on port ${PORT}); });这段代码做了几件事创建 Express 应用用express.json()解析请求体这样req.body才能拿到 JSON 数据aliyun.com加了一个简单的日志中间件方便观察请求耗时把/tasks路由交给routes/tasks.js处理七、写路由routes/tasks.js核心 CRUD// routes/tasks.js const express require(express); const router express.Router(); // 示例数据内存里的“数据库” let tasks [ { id: 1, title: Buy groceries, description: Milk, Cheese, Pizza, Fruit, done: false, }, { id: 2, title: Learn Node.js, description: Follow a Node.js tutorial and build a REST API, done: false, }, ]; let nextId 3; // 获取所有任务 router.get(/, (req, res) { res.json({ tasks }); }); // 获取单个任务 router.get(/:id, (req, res) { const taskId parseInt(req.params.id, 10); const task tasks.find(t t.id taskId); if (!task) { return res.status(404).json({ message: Task not found }); } res.json(task); }); // 创建新任务 router.post(/, (req, res) { const { title, description } req.body; if (!title) { return res.status(400).json({ message: title is required }); } const newTask { id: nextId, title, description: description || , done: false, }; tasks.push(newTask); res.status(201).json(newTask); }); // 更新任务 router.put(/:id, (req, res) { const taskId parseInt(req.params.id, 10); const task tasks.find(t t.id taskId); if (!task) { return res.status(404).json({ message: Task not found }); } const { title, description, done } req.body; task.title title || task.title; task.description description || task.description; task.done done ! undefined ? done : task.done; res.json(task); }); // 删除任务 router.delete(/:id, (req, res) { const taskId parseInt(req.params.id, 10); const task tasks.find(t t.id taskId); if (!task) { return res.status(404).json({ message: Task not found }); } const index tasks.indexOf(task); tasks.splice(index, 1); res.json({ result: true }); }); module.exports router;这个文件的结构参考了阿里云社区一个 2024 年的 Node.js REST 教程但做了更清晰的错误处理和参数校验aliyun.com。八、跑起来 用 curl 测试1. 启动服务器npm start终端会看到Server is running on port 30002. 测试 CRUD获取所有任务curl http://localhost:3000/tasks获取单个任务curl http://localhost:3000/tasks/1创建新任务curl -X POST \ -H Content-Type: application/json \ -d {title:Learn Node.js} \ http://localhost:3000/tasks更新任务curl -X PUT \ -H Content-Type: application/json \ -d {title:Master Node.js, done: true} \ http://localhost:3000/tasks/3删除任务curl -X DELETE http://localhost:3000/tasks/1如果你用 Postman可以直接把这些 URL 和方法配置进去更直观csdn.net。九、加点“工程味”错误处理 输入校验2025 年的 Node.js API 实战里输入校验 统一错误格式是基本要求dev.to。1. 统一错误响应中间件在app.js里加// 统一错误响应格式 app.use((err, req, res, next) { console.error(err.stack); res.status(500).json({ code: 500, message: Internal Server Error, error: process.env.NODE_ENV development ? err.message : undefined, }); });2. 更严格的参数校验比如创建任务时要求title必须是非空字符串router.post(/, (req, res) { const { title, description } req.body; if (!title || typeof title ! string || !title.trim()) { return res.status(400).json({ code: 400, message: title must be a non-empty string, }); } // ... 创建任务逻辑 });⚠️ 注意永远不要信任客户端输入这是 2025 年 API 安全的第一条原则dev.to。十、避坑指南新手最容易踩的坑端口被占用EADDRINUSE换一个端口PORT3001 npm start或者杀掉占用进程lsof -i :3000macOS/Linux请求体解析失败忘记app.use(express.json())→req.body是undefined忘记设置Content-Type: application/json→ 解析失败id 类型不一致URL 里的req.params.id是字符串要parseInt再和数字比较否则1 1为false导致找不到任务修改数据没重启服务用nodemon可以自动重启避免手动重启