Mastering Express servers, API routing, HTTP testing, Swagger documentation, and error handling 掌握 Express 服务器、API 路由、HTTP 测试、Swagger 文档与错误处理
Understanding how HTTP, Express, req/res, JSON, Jest, curl, and other technologies work together in layers
理解 HTTP、Express、req/res、JSON、Jest、curl 和其他技术如何在层次中协同工作
Build robust Express servers with proper routing configuration, middleware usage patterns, and request-response cycle management.
构建具有适当路由配置、中间件使用模式和请求-响应循环管理的健壮 Express 服务器。
Design RESTful API routes that wrap existing business logic, handle route parameters, and parse request bodies correctly.
设计 RESTful API 路由,包装现有业务逻辑、处理路由参数并正确解析请求体。
Write comprehensive HTTP integration tests using sync-request-curl and Jest to verify all endpoints under different scenarios.
使用 sync-request-curl 和 Jest 编写全面的 HTTP 集成测试,验证不同场景下的所有端点。
Leverage Swagger documentation to understand API specifications, explore interactive docs, and identify data type requirements.
利用 Swagger 文档理解 API 规范、探索交互式文档并识别数据类型要求。
Implement sophisticated error handling that returns appropriate HTTP status codes for different error scenarios.
实现复杂的错误处理,为不同错误场景返回适当的 HTTP 状态码。
import express from 'express';
const app = express();
const port = 3000;
// Middleware to parse JSON request bodies
app.use(express.json());
// Basic route
app.get('/hello', (req, res) => {
res.json({ message: 'Hello World' });
});
// Start the server
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
This example demonstrates basic Express server initialization with JSON middleware. The server listens on port 3000 and responds to GET requests at /hello.
此示例演示了使用 JSON 中间件的基础 Express 服务器初始化。服务器监听 3000 端口并响应 /hello 的 GET 请求。
// people.ts - existing business logic
export function addPerson(name: string, age: number) {
if (name === '') {
return { error: 'INVALID_NAME' };
}
if (age <= 0) {
return { error: 'INVALID_AGE' };
}
// ... add person logic
return {};
}
// server.ts - HTTP wrapper
import { addPerson } from './people';
app.post('/people/add', (req, res) => {
const { name, age } = req.body;
const result = addPerson(name, age);
if ('error' in result) {
return res.status(400).json(result);
}
return res.status(200).json(result);
});
This pattern shows how to wrap existing functions into HTTP endpoints. The server route acts as a thin wrapper around business logic.
此模式展示了如何将现有函数包装为 HTTP 端点。服务器路由充当业务逻辑的薄包装。
import request from 'sync-request-curl';
describe('POST /people/add', () => {
test('Successfully adds a person', () => {
const res = request(
'POST',
'http://localhost:3000/people/add',
{
json: {
name: 'Alice',
age: 25
}
}
);
const bodyObj = JSON.parse(res.body.toString());
expect(res.statusCode).toBe(200);
expect(bodyObj).toEqual({});
});
test('Rejects empty name with 400', () => {
const res = request(
'POST',
'http://localhost:3000/people/add',
{
json: {
name: '',
age: 25
}
}
);
expect(res.statusCode).toBe(400);
const bodyObj = JSON.parse(res.body.toString());
expect(bodyObj.error).toBe('INVALID_NAME');
});
});
HTTP tests verify endpoint behavior by making real HTTP requests. This replaces direct function calls with server requests.
HTTP 测试通过发起真实的 HTTP 请求来验证端点行为。这将直接函数调用替换为服务器请求。
app.post('/people/add', (req, res) => {
const { name, age } = req.body;
// 401 Unauthorized errors
if (name === '') {
return res.status(401).json({ error: 'INVALID_NAME' });
}
// 400 Bad Request errors
if (age <= 0) {
return res.status(400).json({ error: 'INVALID_AGE' });
}
const result = addPerson(name, age);
if ('error' in result && result.error === 'DUPLICATE_NAME') {
return res.status(400).json(result);
}
return res.status(200).json(result);
});
Different error conditions return different status codes. This helps clients understand what went wrong and how to fix it.
不同的错误条件返回不同的状态码。这有助于客户端理解出了什么问题以及如何修复。
# swagger.yaml
paths:
/people/add:
post:
summary: Add a new person
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
age:
type: number
responses:
'200':
description: Success
'400':
description: Bad Request - Invalid age or duplicate name
'401':
description: Unauthorized - Invalid name (empty string)
Swagger documentation specifies the API contract. Use the "Model" button to see data types and the "Example Value" for sample payloads.
Swagger 文档指定 API 契约。使用"模型"按钮查看数据类型,使用"示例值"查看示例负载。
Head to Week 5 Quiz to test your knowledge with 40+ comprehensive questions. 前往 第5周测验 通过 40+ 道综合题目测试你的知识。
Recommended reading: Tutorial 5 materials, Express documentation, Swagger/OpenAPI specifications, and course lecture slides on HTTP servers. 推荐阅读:教程 5 材料、Express 文档、Swagger/OpenAPI 规范,以及关于 HTTP 服务器的课程讲座幻灯片。