电商平台 API 教程

1. 简介

在本教程中,我们将学习如何使用 Express.js 构建一个简单的电商平台 API。我们将涵盖从基础的路由设置到数据库连接、身份认证、文件上传处理等高级主题。通过本教程,你将能够理解如何设计和实现一个功能齐全的电商平台 API。

2. 环境搭建

2.1 Node.js 和 npm 安装

首先,确保你已经安装了 Node.js 和 npm。你可以通过以下命令检查是否已安装:

node -v
npm -v

如果没有安装,请访问 Node.js 官网 下载并安装。

2.2 创建项目目录

创建一个新的项目目录并初始化 npm:

mkdir ecommerce-api
cd ecommerce-api
npm init -y

2.3 安装 Express.js

使用 npm 安装 Express.js:

npm install express

3. 创建第一个 Express.js 应用

3.1 创建入口文件

在项目根目录下创建一个 index.js 文件,并添加以下代码:

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Welcome to the E-commerce API!');
});

app.listen(port, () => {
  console.log(`Server is running on http://localhost:${port}`);
});

3.2 运行应用

在终端中运行以下命令启动服务器:

node index.js

打开浏览器访问 http://localhost:3000,你应该会看到 "Welcome to the E-commerce API!" 的消息。

4. 路由基础

4.1 定义路由

在 Express.js 中,路由用于处理不同的 HTTP 请求。我们可以通过 app.get, app.post, app.put, app.delete 等方法定义路由。

app.get('/products', (req, res) => {
  res.send('List of products');
});

app.post('/products', (req, res) => {
  res.send('Product created');
});

4.2 实践练习

尝试添加一个 /users 路由,用于获取用户列表和创建新用户。

5. 中间件概念

5.1 什么是中间件?

中间件是 Express.js 的核心概念之一。它是一个函数,可以访问请求对象 (req)、响应对象 (res) 以及下一个中间件函数 (next)。

5.2 使用中间件

app.use((req, res, next) => {
  console.log('Time:', Date.now());
  next();
});

5.3 实践练习

创建一个中间件,用于记录每个请求的 URL 和时间。

6. 请求和响应对象

6.1 请求对象 (req)

请求对象包含客户端发送的所有信息,如 URL、查询参数、请求头等。

app.get('/products/:id', (req, res) => {
  const productId = req.params.id;
  res.send(`Product ID: ${productId}`);
});

6.2 响应对象 (res)

响应对象用于向客户端发送响应。常用的方法包括 res.send, res.json, res.status 等。

app.get('/products', (req, res) => {
  res.json([{ id: 1, name: 'Product 1' }, { id: 2, name: 'Product 2' }]);
});

6.3 实践练习

创建一个路由,返回一个 JSON 格式的用户列表。

7. 路由进阶

7.1 路由参数

路由参数用于捕获 URL 中的动态部分。

app.get('/products/:id', (req, res) => {
  const productId = req.params.id;
  res.send(`Product ID: ${productId}`);
});

7.2 查询字符串

查询字符串用于传递额外的参数。

app.get('/products', (req, res) => {
  const category = req.query.category;
  res.send(`Category: ${category}`);
});

7.3 实践练习

创建一个路由,根据查询参数返回特定类别的商品。

8. 静态文件服务

8.1 提供静态文件

使用 express.static 中间件提供静态文件服务。

app.use(express.static('public'));

8.2 实践练习

创建一个 public 目录,并在其中放置一些静态文件(如图片、CSS 文件),然后通过浏览器访问这些文件。

9. 模板引擎

9.1 使用 EJS 模板引擎

安装 EJS:

npm install ejs

配置模板引擎:

app.set('view engine', 'ejs');

创建一个视图文件 views/index.ejs:

<!DOCTYPE html>
<html>
<head>
  <title>E-commerce API</title>
</head>
<body>
  <h1>Welcome to the E-commerce API</h1>
</body>
</html>

渲染视图:

app.get('/', (req, res) => {
  res.render('index');
});

9.2 实践练习

创建一个视图文件,显示商品列表。

10. 错误处理

10.1 处理 404 错误

app.use((req, res, next) => {
  res.status(404).send('Page not found');
});

10.2 处理其他错误

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

10.3 实践练习

创建一个自定义错误处理中间件,记录错误日志并返回友好的错误信息。

11. 常用中间件介绍

11.1 body-parser

用于解析请求体。

npm install body-parser
const bodyParser = require('body-parser');
app.use(bodyParser.json());

11.2 morgan

用于日志记录。

npm install morgan
const morgan = require('morgan');
app.use(morgan('combined'));

11.3 实践练习

集成 body-parser 和 morgan 中间件,并测试其功能。

12. 自定义中间件开发

12.1 创建自定义中间件

const logger = (req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
};

app.use(logger);

12.2 实践练习

创建一个中间件,用于检查请求头中的 API 密钥。

13. 第三方中间件集成

13.1 集成 helmet

用于增强应用的安全性。

npm install helmet
const helmet = require('helmet');
app.use(helmet());

13.2 实践练习

集成 helmet 中间件,并测试其功能。

14. 身份认证中间件

14.1 使用 Passport.js

安装 Passport.js:

npm install passport passport-local

配置 Passport:

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  (username, password, done) => {
    // 验证逻辑
  }
));

app.use(passport.initialize());
app.use(passport.session());

14.2 实践练习

创建一个简单的用户认证系统,使用 Passport.js 进行用户登录和注册。

15. 文件上传处理

15.1 使用 multer

安装 multer:

npm install multer

配置 multer:

const multer = require('multer');
const upload = multer({ dest: 'uploads/' });

app.post('/upload', upload.single('file'), (req, res) => {
  res.send('File uploaded');
});

15.2 实践练习

创建一个文件上传接口,允许用户上传商品图片。

16. MongoDB 与 Mongoose

16.1 安装 Mongoose

npm install mongoose

16.2 连接 MongoDB

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/ecommerce', { useNewUrlParser: true, useUnifiedTopology: true });

16.3 定义模型

const productSchema = new mongoose.Schema({
  name: String,
  price: Number
});

const Product = mongoose.model('Product', productSchema);

16.4 实践练习

创建一个商品模型,并实现商品的增删改查接口。

17. SQL 数据库 (MySQL, PostgreSQL)

17.1 安装 Sequelize

npm install sequelize
npm install mysql2

17.2 连接数据库

const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: 'mysql'
});

17.3 定义模型

const User = sequelize.define('User', {
  username: {
    type: Sequelize.STRING,
    allowNull: false
  },
  email: {
    type: Sequelize.STRING,
    allowNull: false
  }
});

17.4 实践练习

创建一个用户模型,并实现用户的增删改查接口。

18. ORM 工具 (Sequelize)

18.1 基本操作

User.create({ username: 'john', email: '[email protected]' }).then(user => {
  console.log('User created:', user.toJSON());
});

18.2 实践练习

使用 Sequelize 实现用户的增删改查操作。

19. 数据验证和安全性

19.1 数据验证

使用 Sequelize 的验证功能:

const User = sequelize.define('User', {
  username: {
    type: Sequelize.STRING,
    allowNull: false,
    validate: {
      len: [3, 20]
    }
  }
});

19.2 安全性

使用 helmet 和 cors 增强安全性:

const helmet = require('helmet');
const cors = require('cors');

app.use(helmet());
app.use(cors());

19.3 实践练习

为商品模型添加数据验证,并集成 helmet 和 cors。

20. RESTful 设计原则

20.1 什么是 RESTful API?

RESTful API 是一种基于 HTTP 协议的设计风格,使用标准的 HTTP 方法(GET, POST, PUT, DELETE)进行资源操作。

20.2 实践练习

设计一个符合 RESTful 原则的商品 API。

21. API 版本控制

21.1 版本控制策略

使用 URL 路径或请求头进行版本控制:

app.get('/api/v1/products', (req, res) => {
  res.send('Version 1 products');
});

app.get('/api/v2/products', (req, res) => {
  res.send('Version 2 products');
});

21.2 实践练习

为商品 API 添加版本控制。

22. 数据序列化和反序列化

22.1 序列化

将对象转换为 JSON 格式:

res.json(product);

22.2 反序列化

解析请求体中的 JSON 数据:

app.use(express.json());

22.3 实践练习

实现商品数据的序列化和反序列化。

23. API 文档生成 (Swagger)

23.1 安装 Swagger

npm install swagger-jsdoc swagger-ui-express

23.2 配置 Swagger

const swaggerJsDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');

const swaggerOptions = {
  swaggerDefinition: {
    info: {
      title: 'E-commerce API',
      version: '1.0.0',
    },
  },
  apis: ['index.js'],
};

const swaggerDocs = swaggerJsDoc(swaggerOptions);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs));

23.3 实践练习

为商品 API 生成 Swagger 文档。

24. 缓存策略

24.1 使用 Redis 进行缓存

安装 Redis:

npm install redis

配置 Redis:

const redis = require('redis');
const client = redis.createClient();

client.on('connect', () => {
  console.log('Connected to Redis');
});

24.2 实践练习

使用 Redis 缓存商品数据。

25. 压缩和 GZIP

25.1 使用 compression 中间件

npm install compression
const compression = require('compression');
app.use(compression());

25.2 实践练习

集成 compression 中间件,并测试其功能。

26. 安全最佳实践

26.1 使用 helmet 和 cors

const helmet = require('helmet');
const cors = require('cors');

app.use(helmet());
app.use(cors());

26.2 实践练习

集成 helmet 和 cors,并测试其功能。

27. 跨域资源共享 (CORS)

27.1 使用 cors 中间件

npm install cors
const cors = require('cors');
app.use(cors());

27.2 实践练习

集成 cors 中间件,并测试其功能。

28. 负载均衡

28.1 使用 Nginx 进行负载均衡

配置 Nginx:

http {
  upstream backend {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
  }

  server {
    listen 80;

    location / {
      proxy_pass http://backend;
    }
  }
}

28.2 实践练习

配置 Nginx 进行负载均衡,并测试其功能。

29. 单元测试 (Mocha, Chai)

29.1 安装 Mocha 和 Chai

npm install mocha chai

29.2 编写测试用例

const chai = require('chai');
const chaiHttp = require('chai-http');
const server = require('../index');
const should = chai.should();

chai.use(chaiHttp);

describe('Products', () => {
  it('should list all products on /products GET', (done) => {
    chai.request(