在现代Web应用开发中,API(Application Programming Interface)扮演着至关重要的角色。API允许前端应用与后端服务器进行数据交互,实现动态内容展示和用户交互功能。本教程将指导您如何在Express应用中创建API路由,并将所有API路由组织在/api路径下,以保持项目结构的清晰性和可维护性。

API路由的概念

API路由是Web服务器上处理特定URL路径并返回数据的端点。与传统网页路由不同,API路由通常返回结构化数据(如JSON格式),而不是完整的HTML页面[1]。

将API路由组织在特定路径下(如/api)有以下优势:

  1. 清晰的分离:将API端点与网站页面路由明确分开
  2. 易于维护:统一管理所有API端点
  3. 版本控制:便于未来进行API版本升级(如/api/v1/api/v2
  4. 安全性:可以针对API路由实施专门的安全措施

创建API路由目录结构

为了更好地组织代码,我们建议创建专门的目录来存放路由相关文件。

创建routes目录

在项目根目录下创建routes目录:

1
mkdir routes

创建API子目录

在routes目录下创建api子目录,用于存放所有API路由:

1
2
cd routes
mkdir api

最终的目录结构如下:

1
2
3
4
5
6
7
my-express-app/
├── routes/
│ └── api/
├── public/
├── index.js
├── package.json
└── package-lock.json

创建北京时间API

现在让我们创建一个返回北京时间的API端点。北京时间是东八区时间(UTC+8),在国际项目中经常需要提供时区相关的服务。

创建时间API路由文件

routes/api/目录下创建一个名为time.js的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const express = require('express');
const router = express.Router();

// 获取北京时间的API端点
router.get('/beijing-time', (req, res) => {
// 创建当前时间对象
const now = new Date();

// 设置为北京时间(UTC+8)
const beijingTime = new Date(now.getTime() + (8 * 60 * 60 * 1000));

// 返回JSON格式的响应
res.json({
currentTime: beijingTime.toISOString(),
formattedTime: beijingTime.toLocaleString('zh-CN', {
timeZone: 'Asia/Shanghai',
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}),
timezone: 'Asia/Shanghai',
utcOffset: '+08:00'
});
});

module.exports = router;

代码解释:

  1. express.Router():创建一个新的路由器实例
  2. router.get('/beijing-time', ...):定义处理GET请求的路由
  3. new Date():创建当前时间对象
  4. getTime() + (8 * 60 * 60 * 1000):将UTC时间转换为北京时间(加8小时)
  5. res.json():以JSON格式返回数据
  6. module.exports = router:导出路由器以供其他文件使用

API响应数据说明

API返回的JSON数据包含以下字段:

  • currentTime:ISO格式的北京时间
  • formattedTime:格式化的北京时间字符串
  • timezone:时区标识符
  • utcOffset:相对于UTC的偏移量

集成API路由到主应用

创建了API路由文件后,需要将其集成到主Express应用中。

更新主应用文件

修改项目根目录下的index.js文件,添加API路由:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const express = require('express');
const path = require('path');
const timeRoutes = require('./routes/api/time');

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

// 提供静态文件服务
app.use(express.static('public'));

// 添加API路由前缀
app.use('/api', timeRoutes);

// 处理根路径请求,返回主页
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});

代码解释:

  1. const timeRoutes = require('./routes/api/time'):引入时间API路由模块
  2. app.use('/api', timeRoutes):将所有以/api开头的请求路由到timeRoutes处理器
  3. 这意味着/api/beijing-time路径将由我们在time.js中定义的路由处理

API路由路径解析

通过以上配置,API端点的完整路径为:

  • 北京时间API:http://localhost:3000/api/beijing-time

当用户访问该路径时,请求处理流程如下:

  1. Express接收到/api/beijing-time请求
  2. app.use('/api', timeRoutes)匹配到/api前缀
  3. 剩余路径/beijing-time被传递给timeRoutes路由器
  4. timeRoutes中的router.get('/beijing-time', ...)处理该请求
  5. 返回JSON格式的北京时间数据

测试API路由

启动服务器

确保所有文件都已正确配置后,启动Express应用:

1
npm start

访问API端点

打开浏览器或使用curl命令访问API端点:

1
curl http://localhost:3000/api/beijing-time

您应该会收到类似以下格式的JSON响应:

1
2
3
4
5
6
{
"currentTime": "2025-10-30T10:30:45.123Z",
"formattedTime": "2025/10/30 18:30:45",
"timezone": "Asia/Shanghai",
"utcOffset": "+08:00"
}

在浏览器中测试

您也可以直接在浏览器地址栏中输入以下URL来测试API:

1
http://localhost:3000/api/beijing-time

现代浏览器通常会格式化显示JSON数据,便于查看。

扩展API路由

添加更多时间相关API

可以在同一个路由文件中添加更多时间相关的API端点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
const express = require('express');
const router = express.Router();

// 获取北京时间的API端点
router.get('/beijing-time', (req, res) => {
const now = new Date();
const beijingTime = new Date(now.getTime() + (8 * 60 * 60 * 1000));

res.json({
currentTime: beijingTime.toISOString(),
formattedTime: beijingTime.toLocaleString('zh-CN', {
timeZone: 'Asia/Shanghai',
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}),
timezone: 'Asia/Shanghai',
utcOffset: '+08:00'
});
});

// 获取UTC时间的API端点
router.get('/utc-time', (req, res) => {
const now = new Date();

res.json({
currentTime: now.toISOString(),
formattedTime: now.toUTCString(),
timezone: 'UTC',
utcOffset: '+00:00'
});
});

// 获取多个时区时间的API端点
router.get('/world-time', (req, res) => {
const now = new Date();

const timeZones = {
'Asia/Shanghai': now.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }),
'America/New_York': now.toLocaleString('zh-CN', { timeZone: 'America/New_York' }),
'Europe/London': now.toLocaleString('zh-CN', { timeZone: 'Europe/London' }),
'Asia/Tokyo': now.toLocaleString('zh-CN', { timeZone: 'Asia/Tokyo' })
};

res.json({
currentTime: now.toISOString(),
timeZones: timeZones
});
});

module.exports = router;

创建独立的API路由文件

对于更复杂的项目,建议为不同功能创建独立的路由文件:

1
2
3
4
5
6
routes/
└── api/
├── time.js
├── user.js
├── product.js
└── order.js

然后在主应用文件中统一引入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const express = require('express');
const path = require('path');
const timeRoutes = require('./routes/api/time');
const userRoutes = require('./routes/api/user');
const productRoutes = require('./routes/api/product');

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

// 提供静态文件服务
app.use(express.static('public'));

// 添加API路由
app.use('/api/time', timeRoutes);
app.use('/api/user', userRoutes);
app.use('/api/product', productRoutes);

// 处理根路径请求,返回主页
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});

API路由最佳实践

  1. 统一前缀:所有API路由使用统一前缀(如/api
  2. 版本控制:考虑为API添加版本号(如/api/v1
  3. 语义化路径:使用清晰、语义化的路径命名
  4. HTTP状态码:正确使用HTTP状态码表示请求结果
  5. 错误处理:实现统一的错误处理机制
  6. 数据格式:统一使用JSON格式返回数据
  7. 安全性:对敏感API实施身份验证和授权

在前端使用API

可以在前端JavaScript中使用API获取数据并更新页面内容:

1
2
3
4
5
6
7
8
9
// 获取北京时间并更新页面
fetch('/api/beijing-time')
.then(response => response.json())
.then(data => {
document.getElementById('time-display').innerText = data.formattedTime;
})
.catch(error => {
console.error('Error fetching time:', error);
});

总结

通过本教程,我们学习了如何:

  1. 理解API路由的概念和优势
  2. 创建合理的API路由目录结构
  3. 编写返回北京时间的API端点
  4. 将API路由集成到Express主应用中
  5. 测试API路由功能
  6. 扩展API路由功能
  7. 遵循API路由最佳实践

这些技能为构建功能完整的Web应用奠定了基础,使您的应用能够提供动态数据服务。

参考文献

[1] Express.js, “Express - Node.js web application framework,” 2023. [Online]. Available: https://expressjs.com/. [Accessed: Oct. 30, 2025].


© 2025 MikeWu597 使用 Stellar 创建

琼ICP备2023004663号-3
湘公网安备 43010302001556号