# 实现开发最佳实践
# 引言
基于规范进行实现开发是 SDD 的核心环节。本章将介绍如何基于规范进行高效的实现开发。
# 开发流程
# 1. 规范理解
在开始编码之前,深入理解规范:
理解步骤:
1. 阅读规范全文
2. 理解功能需求
3. 理解业务规则
4. 理解边界条件
5. 理解安全要求
6. 理解性能要求
7. 提出问题和澄清
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2. 技术设计
基于规范进行技术设计:
设计内容:
- 数据库设计
- API 路由设计
- 业务逻辑设计
- 错误处理设计
- 安全实现设计
- 性能优化设计
1
2
3
4
5
6
7
2
3
4
5
6
7
# 3. 实现开发
按照规范实现功能:
实现原则:
- 严格遵循规范
- 实现所有定义的功能
- 处理所有边界情况
- 满足性能要求
- 满足安全要求
1
2
3
4
5
6
2
3
4
5
6
# 4. 规范验证
验证实现是否符合规范:
验证内容:
- 请求处理正确
- 响应格式正确
- 状态码正确
- 错误处理正确
- 边界情况处理
1
2
3
4
5
6
2
3
4
5
6
# 实现策略
# 1. 自顶向下实现
从 API 接口开始,逐步实现:
// 1. 定义路由
app.post('/api/v1/users', createUser);
// 2. 实现控制器
async function createUser(req, res) {
try {
// 3. 验证输入
const { email, password, name } = validateInput(req.body);
// 4. 业务逻辑
const user = await userService.createUser({ email, password, name });
// 5. 返回响应
res.status(201).json(user);
} catch (error) {
// 6. 错误处理
handleError(error, res);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 2. 测试驱动开发(TDD)
基于规范编写测试,然后实现:
// 1. 编写测试(基于规范)
describe('POST /api/v1/users', () => {
it('should create user with valid data', async () => {
const response = await request
.post('/api/v1/users')
.send({
email: 'user@example.com',
password: 'SecurePass123',
name: 'John Doe'
});
expect(response.status).toBe(201);
expect(response.body).toMatchSchema(userSchema);
});
it('should return 400 for invalid email', async () => {
const response = await request
.post('/api/v1/users')
.send({
email: 'invalid-email',
password: 'SecurePass123'
});
expect(response.status).toBe(400);
expect(response.body.errors).toContainEqual({
field: 'email',
message: 'Invalid email format'
});
});
});
// 2. 运行测试(失败)
// 3. 实现功能
// 4. 运行测试(通过)
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
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
# 3. 契约测试
使用契约测试确保实现符合规范:
// 使用 Dredd 进行契约测试
const dredd = require('dredd');
const config = {
server: 'http://localhost:3000',
options: {
path: ['./api-spec.yaml'],
dry-run: false,
silent: false
}
};
dredd(config, (err, stats) => {
if (err) {
console.error('Contract test failed:', err);
process.exit(1);
}
console.log('Contract test passed');
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 实现技巧
# 1. 输入验证
严格验证输入,符合规范要求:
// 使用 Joi 进行验证
const Joi = require('joi');
const userSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string()
.min(8)
.max(128)
.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/)
.required(),
name: Joi.string().min(1).max(50).optional()
});
function validateInput(data) {
const { error, value } = userSchema.validate(data);
if (error) {
throw new ValidationError(error.details);
}
return value;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2. 错误处理
按照规范处理错误:
// 错误处理中间件
function handleError(error, res) {
if (error instanceof ValidationError) {
return res.status(400).json({
message: 'Validation failed',
errors: error.details.map(detail => ({
field: detail.path.join('.'),
message: detail.message
}))
});
}
if (error instanceof DuplicateEmailError) {
return res.status(409).json({
message: 'Email already registered',
code: 'EMAIL_EXISTS'
});
}
// 其他错误
console.error('Unexpected error:', error);
return res.status(500).json({
message: 'Internal server error',
code: 'INTERNAL_ERROR'
});
}
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
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
# 3. 响应格式化
确保响应格式符合规范:
// 响应格式化
function formatUserResponse(user) {
return {
id: user.id,
email: user.email,
name: user.name,
createdAt: user.createdAt.toISOString()
};
}
// 使用
res.status(201).json(formatUserResponse(user));
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 4. 边界情况处理
处理所有边界情况:
async function getUserById(id) {
// 验证 ID 格式
const userId = parseInt(id);
if (isNaN(userId) || userId < 1 || userId > 2147483647) {
throw new ValidationError('Invalid user ID');
}
// 查询用户
const user = await db.users.findById(userId);
if (!user) {
throw new NotFoundError('User not found');
}
return user;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 规范变更处理
# 1. 规范版本管理
支持多个规范版本:
// 版本路由
app.use('/api/v1', v1Routes);
app.use('/api/v2', v2Routes);
// 版本实现
const v1Routes = require('./routes/v1');
const v2Routes = require('./routes/v2');
1
2
3
4
5
6
7
2
3
4
5
6
7
# 2. 向后兼容
保持向后兼容:
// v1 API
app.get('/api/v1/users/:id', getUserV1);
// v2 API(新功能)
app.get('/api/v2/users/:id', getUserV2);
// v1 实现保持不变
function getUserV1(req, res) {
// 原有实现
}
// v2 实现(扩展)
function getUserV2(req, res) {
// 新实现,但保持兼容
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 3. 废弃处理
处理废弃的 API:
// 废弃的 API
app.get('/api/v1/old-endpoint', (req, res) => {
res.set('Deprecation', 'true');
res.set('Sunset', '2024-12-31');
res.status(200).json({
message: 'This endpoint is deprecated',
migration: '/api/v2/new-endpoint'
});
});
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 性能优化
# 1. 数据库优化
优化数据库查询:
// 使用索引
// 规范要求:查询用户,响应时间 < 200ms
// 优化前
const user = await db.users.findOne({ email });
// 优化后(使用索引)
const user = await db.users.findOne({ email }).hint({ email: 1 });
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2. 缓存策略
使用缓存提高性能:
// 缓存用户数据
const cache = require('redis');
async function getUserById(id) {
// 先查缓存
const cached = await cache.get(`user:${id}`);
if (cached) {
return JSON.parse(cached);
}
// 查数据库
const user = await db.users.findById(id);
// 写入缓存
await cache.setex(`user:${id}`, 3600, JSON.stringify(user));
return user;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 3. 异步处理
使用异步处理提高响应速度:
// 异步发送邮件
async function createUser(userData) {
// 创建用户
const user = await db.users.create(userData);
// 异步发送验证邮件(不阻塞响应)
emailService.sendVerificationEmail(user.email).catch(err => {
console.error('Failed to send email:', err);
});
return user;
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 安全实现
# 1. 输入验证
严格验证所有输入:
// 使用验证库
const validator = require('validator');
function validateEmail(email) {
if (!validator.isEmail(email)) {
throw new ValidationError('Invalid email format');
}
return validator.normalizeEmail(email);
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 2. SQL 注入防护
使用参数化查询:
// 错误:SQL 注入风险
const query = `SELECT * FROM users WHERE email = '${email}'`;
// 正确:参数化查询
const query = 'SELECT * FROM users WHERE email = ?';
const user = await db.query(query, [email]);
1
2
3
4
5
6
2
3
4
5
6
# 3. XSS 防护
转义输出:
// 使用转义库
const escape = require('escape-html');
function formatUserResponse(user) {
return {
id: user.id,
email: user.email,
name: escape(user.name), // 转义 HTML
createdAt: user.createdAt.toISOString()
};
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 4. 密码安全
安全处理密码:
// 使用 bcrypt 哈希密码
const bcrypt = require('bcrypt');
async function hashPassword(password) {
const saltRounds = 10;
return await bcrypt.hash(password, saltRounds);
}
async function verifyPassword(password, hash) {
return await bcrypt.compare(password, hash);
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 测试策略
# 1. 单元测试
测试单个功能:
describe('UserService', () => {
describe('createUser', () => {
it('should create user with valid data', async () => {
const userData = {
email: 'user@example.com',
password: 'SecurePass123',
name: 'John Doe'
};
const user = await userService.createUser(userData);
expect(user).toMatchSchema(userSchema);
expect(user.email).toBe(userData.email);
});
});
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 2. 集成测试
测试 API 端点:
describe('POST /api/v1/users', () => {
it('should return 201 with user object', async () => {
const response = await request
.post('/api/v1/users')
.send({
email: 'user@example.com',
password: 'SecurePass123',
name: 'John Doe'
});
expect(response.status).toBe(201);
expect(response.body).toMatchSchema(userSchema);
});
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3. 契约测试
验证实现符合规范:
// 使用 Dredd
const config = {
server: 'http://localhost:3000',
options: {
path: ['./api-spec.yaml']
}
};
dredd(config);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 总结
实现开发的关键:
- 理解规范 - 深入理解规范要求
- 严格实现 - 严格按照规范实现
- 全面测试 - 测试所有功能和边界情况
- 持续验证 - 持续验证实现符合规范
- 性能优化 - 满足性能要求
- 安全实现 - 满足安全要求
在下一节中,我们将学习测试策略。