Node.js后端开发入门
Node.js让JavaScript从浏览器走向了服务器,使得前端开发者能够使用同一门语言完成全栈开发。这一变革性的技术不仅打破了前后端的边界,还催生了无数的Web应用和服务。在这篇文章中,我将带你从零开始学习Node.js后端开发,掌握构建现代Web服务的核心技能。
理解Node.js
Node.js是基于Chrome V8引擎的JavaScript运行时,它让JavaScript可以在服务端运行。与浏览器环境不同,Node.js提供了文件系统、网络、进程等底层API,让JavaScript具备了完整的服务端能力。
Node.js的特点
- 事件驱动:基于事件循环模型,高效处理并发
- 非阻塞I/O:I/O操作不会阻塞主线程
- 单线程:主线程单线程,通过事件循环处理并发
- 跨平台:支持Windows、macOS、Linux
- 丰富的包管理:npm拥有世界上最大的开源库生态系统
适用场景
Node.js特别适合I/O密集型应用:Web服务器、API服务、实时通信、数据流处理等。但对于CPU密集型任务(如视频编码、科学计算),Node.js不是最佳选择,因为计算会阻塞事件循环。
快速开始
安装Node.js
推荐使用nvm(Node Version Manager)安装和管理Node.js版本:
# 安装nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# 安装Node.js
nvm install --lts
nvm use --lts
# 验证安装
node -v
npm -v
第一个Node.js程序
// app.js
console.log('Hello, Node.js!');
// 运行
// node app.js
创建HTTP服务器
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
});
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
包管理器npm
package.json
{
"name": "my-app",
"version": "1.0.0",
"description": "A Node.js application",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest"
},
"dependencies": {
"express": "^4.18.0"
},
"devDependencies": {
"nodemon": "^3.0.0"
}
}
常用命令
# 初始化项目
npm init -y
# 安装依赖
npm install express
npm install -D nodemon
# 全局安装
npm install -g pm2
# 运行脚本
npm run dev
Express框架
Express是Node.js最流行的Web框架,简洁灵活,适合构建各种Web应用。
基础使用
const express = require('express');
const app = express();
// 中间件:解析JSON请求体
app.use(express.json());
// 路由
app.get('/', (req, res) => {
res.json({ message: 'Hello API' });
});
app.post('/users', (req, res) => {
const { name, email } = req.body;
// 创建用户逻辑
res.status(201).json({ id: 1, name, email });
});
app.put('/users/:id', (req, res) => {
const { id } = req.params;
const { name } = req.body;
// 更新用户逻辑
res.json({ id, name });
});
app.delete('/users/:id', (req, res) => {
// 删除用户逻辑
res.status(204).end();
});
// 错误处理
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong!' });
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
中间件
中间件是Express的核心概念,它是在请求和响应之间执行的函数:
// 日志中间件
app.use((req, res, next) => {
console.log(`${req.method} ${req.path} - ${new Date().toISOString()}`);
next();
});
// 身份验证中间件
function authMiddleware(req, res, next) {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
// 验证token
req.user = verifyToken(token);
next();
}
// 在特定路由使用
app.get('/profile', authMiddleware, (req, res) => {
res.json({ user: req.user });
});
数据库操作
MongoDB
const mongoose = require('mongoose');
// 连接数据库
mongoose.connect('mongodb://localhost/myapp');
// 定义模型
const UserSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
createdAt: { type: Date, default: Date.now }
});
const User = mongoose.model('User', UserSchema);
// CRUD操作
async function createUser(data) {
return await User.create(data);
}
async function findUser(id) {
return await User.findById(id);
}
async function updateUser(id, data) {
return await User.findByIdAndUpdate(id, data, { new: true });
}
async function deleteUser(id) {
return await User.findByIdAndDelete(id);
}
SQL数据库(PostgreSQL)
const { Pool } = require('pg');
const pool = new Pool({
host: 'localhost',
database: 'myapp',
user: 'postgres',
password: 'password'
});
// 查询
async function getUsers() {
const { rows } = await pool.query('SELECT * FROM users');
return rows;
}
async function createUser(name, email) {
const { rows } = await pool.query(
'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',
[name, email]
);
return rows[0];
}
安全性
安全中间件
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const cors = require('cors');
// 安全HTTP头
app.use(helmet());
// CORS
app.use(cors({
origin: 'https://myapp.com',
credentials: true
}));
// 速率限制
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100 // 每IP最多100个请求
});
app.use('/api/', limiter);
输入验证
const { body, validationResult } = require('express-validator');
app.post('/users',
body('email').isEmail().normalizeEmail(),
body('name').trim().notEmpty().escape(),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// 处理请求
}
);
部署
PM2进程管理
# 安装PM2
npm install -g pm2
# 启动应用
pm2 start app.js --name "myapp"
# 查看状态
pm2 status
# 日志
pm2 logs myapp
# 开机自启
pm2 startup
pm2 save
Docker部署
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
最佳实践
- 使用异步/await:避免回调地狱,代码更清晰
- 环境变量管理:使用dotenv管理配置
- 统一错误处理:集中处理异常,避免崩溃
- 日志记录:使用winston或pino记录日志
- API文档:使用Swagger自动生成文档
- 单元测试:使用Jest编写测试
- 安全检查:使用npm audit检查依赖漏洞
总结
Node.js为前端开发者打开了后端的大门,让你可以用同一门语言完成全栈开发。从理解事件循环开始,掌握Express框架、数据库操作、安全防护,你就能构建出生产级别的Web服务。
继续学习:深入学习TypeScript与Node.js结合、微服务架构、消息队列等高级主题,你的Node.js技能会更上一层楼。