Node.js 新手教程:从零开始写自己的服务器端应用
开始前的故事

我记得刚接触 Node.js 那会儿,还是在做前端的时候。那时候用 HTML、CSS 和 JavaScript 做网站页面还行,但每当需要跟后端同学沟通接口时,总觉得有些力不从心。比如我提了个需求:“能不能在登录成功之后返回个 token 啊?”对方反问:“你是要 JWT 还是 session-based 的?你打算怎么验证这个 token?”我一下就懵了——啥是 JWT?session 又是什么?
于是我就下定决心学点后端的东西。后来我找到了 Node.js,它用的是 JavaScript,和我已经熟悉的前端语言一样,上手很快。更重要的是,Node.js 在服务端的表现也非常出色,非常适合构建轻量级的服务端逻辑。
如果你也想入门 Node.js,或者正在学习过程中遇到了困难,不妨看看我这段经历,或许能帮你少走些弯路。
我的第一个 Node 项目:开发一个 API 接口服务

项目背景
那是我第一次独立负责一个项目的后端部分。我们公司要做一个内部使用的员工信息管理系统。UI 已经由前端同事搭好,我需要提供以下几个接口:
/api/employees获取所有员工数据/api/employees/:id获取指定 ID 的员工详情/api/login处理登录请求并返回一个 token/api/logout登出操作
虽然看起来功能简单,但这是我和 Node.js 的初次合作,说实话当时内心很忐忑。
挑战来了:从“只会写前端”到“独立搭建后端服务”

遇到的问题
不会组织项目结构
刚开始写的时候,我把所有的路由处理都写在一个app.js文件里,后来代码越来越多,完全看不懂自己之前写的啥。API 请求的流程不了解
例如,POST 提交数据怎么接收?怎么把 JSON 返回给前端?这些都让我困惑了一阵子。如何做用户认证?JWT 是什么鬼?
登录之后需要返回 token,前端每次请求带上这个 token 才能获取数据。这时候才知道原来还有 token 认证这种机制。数据库连接和查询不会弄
后来我用了 MySQL 数据库,发现怎么连数据库都不会……更别说执行 SQL 语句了。
解决方案:一步步搭建你的第一个 Node 应用

技术选型
为了快速上手,我选择了一个非常流行的 Express 框架来构建服务端程序,加上一些常用的中间件工具,比如:
- Express:核心框架,用来处理 HTTP 请求
- body-parser:用来解析 POST 请求中的参数
- mysql2:连接和操作 MySQL 数据库
- jsonwebtoken (JWT):实现简单的用户认证系统
- dotenv:用于管理环境变量(避免敏感信息直接写进代码)
目录结构规划
随着项目越写越大,我发现良好的目录结构真的很重要。所以我最后整理成了如下结构:
/my-project
│
├── app.js # 主程序入口
├── server.js # 启动服务
├── routes/ # 路由文件
│ ├── auth.routes.js
│ └── employee.routes.js
├── controllers/ # 控制器,处理具体业务逻辑
│ ├── auth.controller.js
│ └── employee.controller.js
├── models/ # 数据模型和数据库交互
│ ├── employee.model.js
│ └── db.js # 数据库配置和连接
├── config/
│ └── jwt.config.js # JWT 密钥等配置
└── .env # 环境变量文件
这套结构清晰又容易扩展,推荐给刚开始写项目的小伙伴。
实操过程详解:编写第一个 API 接口
初始化项目
首先我们要初始化 Node.js 项目:
mkdir my-node-server
cd my-node-server
npm init -y
然后安装必要的包:
npm install express mysql2 dotenv jsonwebtoken body-parser
编写主程序入口:app.js
const express = require('express');
const bodyParser = require('body-parser');
const dotenv = require('dotenv');
dotenv.config(); // 加载 .env 文件中的环境变量
const app = express();
// 解析 application/json 请求体
app.use(bodyParser.json());
// 引入路由
const employeeRoutes = require('./routes/employee.routes');
const authRoutes = require('./routes/auth.routes');
app.use('/api/employees', employeeRoutes);
app.use('/api', authRoutes);
module.exports = app;
启动服务:server.js
const app = require('./app');
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
运行命令启动服务:
node server.js
如果看到 Server is running on port 3000,说明服务已经起来了!
编写员工数据接口:GET /api/employees
1. 数据库配置 (models/db.js)
const mysql = require('mysql2');
require('dotenv').config();
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
module.exports = pool.promise();
.env 文件内容如下:
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=mysecretpassword
DB_NAME=company_db
JWT_SECRET=thisisasecretkey
PORT=3000
2. 查询员工列表 (controllers/employee.controller.js)
const db = require('../models/db');
const getEmployees = async (req, res) => {
try {
const [rows] = await db.query('SELECT * FROM employees');
res.status(200).json(rows);
} catch (err) {
res.status(500).json({ message: 'Server error' });
}
};
module.exports = { getEmployees };
3. 路由注册 (routes/employee.routes.js)
const express = require('express');
const router = express.Router();
const { getEmployees } = require('../controllers/employee.controller');
router.get('/', getEmployees);
module.exports = router;
现在访问 http://localhost:3000/api/employees 就能看到数据啦!
实现登录接口与 JWT 认证
1. 安装 JWT 包
上面我们已经装好了 jsonwebtoken,现在可以使用了。
2. 登录接口 (controllers/auth.controller.js)
const db = require('../models/db');
const jwt = require('jsonwebtoken');
const config = require('../config/jwt.config');
const login = async (req, res) => {
const { username, password } = req.body;
try {
// 从数据库中查找用户
const [userRows] = await db.query(
'SELECT * FROM users WHERE username = ? AND password = ?',
[username, password]
);
if (userRows.length === 0) {
return res.status(401).json({ message: 'Invalid credentials' });
}
// 生成 token
const token = jwt.sign({ id: userRows[0].id, username }, config.secret, {
expiresIn: '1h'
});
res.status(200).json({ token });
} catch (err) {
res.status(500).json({ message: 'Login failed' });
}
};
module.exports = { login };
3. 添加路由 (routes/auth.routes.js)
const express = require('express');
const router = express.Router();
const { login } = require('../controllers/auth.controller');
router.post('/login', login);
module.exports = router;
这样,用户就可以通过 POST 请求发送用户名和密码到 /api/login 来登录了。
踩坑记:开发过程中踩过的几个大坑
1. 忘记写异步函数的 await
JavaScript 是单线程语言,Node.js 也是基于非阻塞 I/O 的,所以数据库查询必须用 await 或者 .then()。否则就会直接返回 undefined。
async function getData() {
const result = db.query(...); // 忘记 await
}
这种错误会导致数据拿不到,而且调试也不太直观。解决办法就是记得每个异步操作前面都要加 await。
2. token 过期设置不对,导致用户总是被登出
一开始我把 expiresIn 写成了 '1s',结果用户刚登录完就被踢出去了,查了好久才发现是设置时间的问题😅。
3. 使用 MySQL 查询拼接字符串,SQL 注入漏洞
有段时间我是这样写查询的:
const query = `SELECT * FROM users WHERE username = '${username}'`;
这样写非常危险!恶意用户可以通过输入 ' OR '1'='1 绕过安全机制。正确做法是使用参数化查询:
const [rows] = await db.query(
'SELECT * FROM users WHERE username = ?',
[username]
);
效果总结:项目上线后的成果
完成这个项目之后,整个系统的协作效率提升了不少:
- 前端可以直接调用我提供的 API,不需要再频繁找后端沟通接口格式;
- 增加了 JWT 认证,保证了接口的安全性;
- 使用模块化架构后,后续新增功能也变得更容易了。
最让我开心的是,我现在可以独自完成一个完整的前后端小项目了,这对我个人能力提升帮助很大。
给新手的建议与经验分享
1. 不要急于求成,先打好基础
Node.js 本身只是 JavaScript 的运行环境,真正的难点在于理解服务端的工作方式。建议从 Express 开始,了解 HTTP 协议、请求响应流程,再逐步深入异步编程、中间件机制。
2. 动手实践比看文档更重要
书上写的再清楚都不如亲自写一遍代码印象深刻。哪怕只是一个最简单的 GET 请求,动手去实现它,才能真正掌握。
3. 学会使用调试工具
Chrome DevTools、Postman、VS Code 自带的调试功能都非常好用。特别是 Postman,可以很方便地测试各种 API 接口。
4. 关注性能和安全性问题
不要只满足于功能跑通,还要学会优化性能:
- 使用连接池避免频繁连接数据库
- 减少不必要的查询
- 对用户输入做好校验和过滤
5. 持续学习现代架构理念
现在很多团队已经开始采用 RESTful API 规范、GraphQL、微服务架构等现代技术。虽然你现在可能还不需要用到它们,但提前了解一下对未来成长很有帮助。
结语:Node.js 是通向全栈之路的好起点
从一个只会写前端的人,到现在能够写出完整服务端接口,Node.js 给了我极大的信心。它不仅让我对后端工作有了更多了解,也为我打开了通往“全栈工程师”的大门。
如果你也正准备踏上这条旅程,别怕犯错,不怕写烂代码,多练多试,你也能写出属于自己的 Node 应用。
祝你在学习的路上少走弯路,一路顺风!如果你有任何问题,欢迎留言交流 😊
本文内容基于我在实际项目中的经验和踩过的坑,希望能为正在学习 Node.js 的你提供一点参考。

评论 0