Back to COMP1531 Overview 返回 COMP1531 总览

🚀 Week 5: HTTP API & Express Server Building第5周:HTTP API 与 Express 服务器构建

Mastering Express servers, API routing, HTTP testing, Swagger documentation, and error handling 掌握 Express 服务器、API 路由、HTTP 测试、Swagger 文档与错误处理

🎯 Learning Objectives学习目标

🏗️ Technology Stack Relationship Diagram技术栈关系图

Understanding how HTTP, Express, req/res, JSON, Jest, curl, and other technologies work together in layers

理解 HTTP、Express、req/res、JSON、Jest、curl 和其他技术如何在层次中协同工作

📱 Client Application Layer 📱 客户端应用层
User-facing applications that make HTTP requests to your server 向服务器发起 HTTP 请求的用户界面应用程序
Web Browser
Fetch API 获取 API
Mobile App
HTTP Client HTTP 客户端
curl
Command line tool 命令行工具
🌐 HTTP Protocol Layer 🌐 HTTP 协议层
Communication protocol between client and server 客户端和服务器之间的通信协议
HTTP Methods
GET, POST, PUT, DELETE
Status Codes
200, 400, 401, 403, 500
Headers
Content-Type, Authorization
📋 Data Format Layer 📋 数据格式层
Data exchange format for API communication API 通信的数据交换格式
JSON
JavaScript Object Notation JavaScript 对象表示法
Request Body
Data sent to server 发送到服务器的数据
Response Body
Data from server 来自服务器的数据
🖥️ Server Framework Layer 🖥️ 服务器框架层
Application framework that handles HTTP requests and routing 处理 HTTP 请求和路由的应用框架
Express.js
Web framework for Node.js Node.js 的 Web 框架
Middleware
express.json(), CORS express.json(), CORS
Routing
app.get(), app.post() app.get(), app.post()
🔄 Request/Response Objects 🔄 请求/响应对象
Objects that encapsulate HTTP request and response data 封装 HTTP 请求和响应数据的对象
req (Request)
req.params, req.body, req.query req.params, req.body, req.query
res (Response)
res.json(), res.status() res.json(), res.status()
Error Handling
next(), res.status(400) next(), res.status(400)
⚙️ Business Logic Layer ⚙️ 业务逻辑层
Core application logic and data processing 核心应用程序逻辑和数据处理
Domain Functions 领域函数
addPerson(), findUser() addPerson(), findUser()
Data Validation 数据验证
Input checking, sanitization 输入检查、清理
Data Storage 数据存储
Database, file system 数据库、文件系统
🧪 Testing Framework Layer 🧪 测试框架层
Tools and frameworks for testing your HTTP endpoints 用于测试 HTTP 端点的工具和框架
Jest
Test runner & assertions 测试运行器和断言
sync-request-curl
HTTP requests in tests 测试中的 HTTP 请求
Integration Tests
End-to-end testing 端到端测试
📚 Documentation Layer 📚 文档层
API documentation and specification tools API 文档和规范工具
Swagger/OpenAPI
API specification API 规范
Interactive Docs
Try API endpoints 尝试 API 端点

🔄 How It All Works Together 🔄 所有技术如何协同工作

  1. Client Request: Browser/mobile app uses HTTP methods (GET, POST) to send JSON data 客户端请求:浏览器/移动应用使用 HTTP 方法(GET、POST)发送 JSON 数据
  2. Express Server: Receives request, routes to appropriate handler using middleware Express 服务器:接收请求,使用中间件路由到适当的处理器
  3. req/res Objects: Express provides req (request) and res (response) objects to handle data req/res 对象:Express 提供 req(请求)和 res(响应)对象来处理数据
  4. Business Logic: Route handlers call domain functions with validated data 业务逻辑:路由处理器使用经过验证的数据调用领域函数
  5. Response: Server sends JSON response with appropriate HTTP status code 响应:服务器发送带有适当 HTTP 状态码的 JSON 响应
  6. Testing: Jest + sync-request-curl simulate client requests to verify behavior 测试:Jest + sync-request-curl 模拟客户端请求来验证行为
  7. Documentation: Swagger documents API contracts for developers 文档:Swagger 为开发者记录 API 契约

🧠 Core Concepts from Tutorial 5核心概念(教程5)

🏗️ Express Server BuildingExpress 服务器构建

Build robust Express servers with proper routing configuration, middleware usage patterns, and request-response cycle management.

构建具有适当路由配置、中间件使用模式和请求-响应循环管理的健壮 Express 服务器。

  • Route configuration and organization路由配置与组织
  • Middleware usage patterns (express.json())中间件使用模式 (express.json())
  • Request-response cycle handling请求-响应循环处理

🛣️ API Route DesignAPI 路由设计

Design RESTful API routes that wrap existing business logic, handle route parameters, and parse request bodies correctly.

设计 RESTful API 路由,包装现有业务逻辑、处理路由参数并正确解析请求体。

  • RESTful design principles (GET, POST, PUT, DELETE)RESTful 设计原则 (GET, POST, PUT, DELETE)
  • Route parameters vs Query parameters vs Body路由参数 vs 查询参数 vs 请求体
  • Wrapper functions for business logic业务逻辑的包装函数

🧪 HTTP Testing MethodsHTTP 测试方法

Write comprehensive HTTP integration tests using sync-request-curl and Jest to verify all endpoints under different scenarios.

使用 sync-request-curl 和 Jest 编写全面的 HTTP 集成测试,验证不同场景下的所有端点。

  • Using sync-request-curl for HTTP requests使用 sync-request-curl 发起 HTTP 请求
  • Jest integration testing patternsJest 集成测试模式
  • Test coverage for success and error cases成功和错误情况的测试覆盖率

📚 Swagger/OpenAPI DocumentationSwagger/OpenAPI 文档

Leverage Swagger documentation to understand API specifications, explore interactive docs, and identify data type requirements.

利用 Swagger 文档理解 API 规范、探索交互式文档并识别数据类型要求。

  • Reading API endpoint specifications阅读 API 端点规范
  • Interactive documentation interface交互式文档界面
  • Understanding Example Value vs Model view理解示例值 vs 模型视图

⚠️ Error Handling & Status Codes错误处理与状态码

Implement sophisticated error handling that returns appropriate HTTP status codes for different error scenarios.

实现复杂的错误处理,为不同错误场景返回适当的 HTTP 状态码。

  • 400 Bad Request: Invalid input format400 Bad Request: 无效的输入格式
  • 401 Unauthorized: Authentication failures401 Unauthorized: 认证失败
  • 403 Forbidden & 500 Internal Server Error403 Forbidden 与 500 内部服务器错误

🧪 Worked Examples示例讲解

1. Basic Express Server Setup基础 Express 服务器设置Tutorial 5

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 请求。

2. Wrapping Existing Functions into Routes将现有函数包装为路由Tutorial 5

// 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 端点。服务器路由充当业务逻辑的薄包装。

3. HTTP Testing with sync-request-curl使用 sync-request-curl 进行 HTTP 测试Tutorial 5

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 请求来验证端点行为。这将直接函数调用替换为服务器请求。

4. Nuanced Error Handling with Multiple Status Codes使用多个状态码的细致错误处理Tutorial 5

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.

不同的错误条件返回不同的状态码。这有助于客户端理解出了什么问题以及如何修复。

5. Swagger Documentation UsageSwagger 文档使用Tutorial 5

# 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 契约。使用"模型"按钮查看数据类型,使用"示例值"查看示例负载。

🧩 Exam & Assessment Alignment与考试/作业的对应关系

🧭 Practice Tasks实践任务

📘 Week 5 Quiz Preview第5周测验预览

Head to Week 5 Quiz to test your knowledge with 40+ comprehensive questions. 前往 第5周测验 通过 40+ 道综合题目测试你的知识。

📝 Summary & Further Reading小结与延伸阅读

Recommended reading: Tutorial 5 materials, Express documentation, Swagger/OpenAPI specifications, and course lecture slides on HTTP servers. 推荐阅读:教程 5 材料、Express 文档Swagger/OpenAPI 规范,以及关于 HTTP 服务器的课程讲座幻灯片。