使用 Python 构建 RESTful API:从理论到实践
梳理 REST 核心原则,并以 FastAPI 实现完整的图书管理 CRUD API,涵盖运行、测试与生产级设计要点。
REST(Representational State Transfer,表述性状态转移)是 Roy Fielding 提出的软件架构风格。RESTful API 遵循 REST 原则,通过 HTTP 协议对资源进行操作,具有简洁、可扩展、无状态等优点。无论是前后端分离的 Web 应用,还是移动端、物联网设备,RESTful API 都是数据交互的主流方式。
核心原则
| 原则 | 说明 |
|---|---|
| 资源导向 | 每个 URI 代表一种资源(如 /books) |
| HTTP 方法 | GET(获取)、POST(创建)、PUT/PATCH(更新)、DELETE(删除) |
| 无状态 | 服务器不保存客户端状态,每次请求都包含完整信息 |
| 统一接口 | 使用标准 HTTP 状态码和媒体类型(如 JSON) |
选择 Python 框架
Python 生态中有 Flask 和 FastAPI 两大轻量级框架。FastAPI 具备自动文档、异步支持和更出色的性能,适合新项目;Flask 则简单灵活。本文以 FastAPI 为例,带你快速上手。
实战:图书管理 API
1. 安装依赖
pip install fastapi uvicorn
2. 编写代码(保存为 main.py)
from fastapi import FastAPI, HTTPException from pydantic import BaseModel from typing import List, Optional app = FastAPI(title="图书管理API") # 模拟数据库 books_db = [] book_id_counter = 1 # 定义数据模型(Pydantic) class Book(BaseModel): id: Optional[int] = None title: str author: str year: int # 获取所有图书 @app.get("/books", response_model=List[Book]) async def get_books(): return books_db # 获取单本图书 @app.get("/books/{book_id}", response_model=Book) async def get_book(book_id: int): for book in books_db: if book.id == book_id: return book raise HTTPException(status_code=404, detail="图书不存在") # 添加新图书 @app.post("/books", response_model=Book, status_code=201) async def create_book(book: Book): global book_id_counter book.id = book_id_counter book_id_counter += 1 books_db.append(book) return book # 更新图书(全量更新) @app.put("/books/{book_id}", response_model=Book) async def update_book(book_id: int, updated: Book): for index, book in enumerate(books_db): if book.id == book_id: updated.id = book_id books_db[index] = updated return updated raise HTTPException(status_code=404, detail="图书不存在") # 删除图书 @app.delete("/books/{book_id}", status_code=204) async def delete_book(book_id: int): for index, book in enumerate(books_db): if book.id == book_id: books_db.pop(index) return raise HTTPException(status_code=404, detail="图书不存在")
3. 运行服务
uvicorn main:app --reload
访问 http://127.0.0.1:8000/docs 即可看到自动生成的交互式 API 文档(Swagger UI)。
测试 API
使用 curl 命令或在文档页面直接尝试:
-
GET 所有图书
curl http://127.0.0.1:8000/books -
POST 添加新书
curl -X POST http://127.0.0.1:8000/books \ -H "Content-Type: application/json" \ -d '{"title":"Python编程","author":"Eric","year":2020}' -
GET 单本图书
curl http://127.0.0.1:8000/books/1 -
PUT 更新图书
curl -X PUT http://127.0.0.1:8000/books/1 \ -H "Content-Type: application/json" \ -d '{"title":"Python编程(第2版)","author":"Eric","year":2023}' -
DELETE 删除图书
curl -X DELETE http://127.0.0.1:8000/books/1
如何设计更规范的 REST API
- 使用名词复数表示资源集合:
/books而不是/getBooks。 - 正确使用 HTTP 状态码:
- 200 OK:成功返回数据
- 201 Created:创建成功
- 204 No Content:删除成功
- 400 Bad Request:客户端错误
- 404 Not Found:资源不存在
- 版本管理:在 URL 中加入版本号,如
/v1/books。 - 分页、过滤与排序:通过查询参数实现,如
/books?offset=0&limit=10&author=Eric。 - 身份认证:常用 JWT(JSON Web Token)或 OAuth2,FastAPI 提供了
fastapi.security模块简化实现。
与 Flask 的对比
如果用 Flask 编写,代码量会多一些,也需要手动处理 JSON 序列化和状态码。FastAPI 基于 Python 类型注解,自动校验请求体、生成文档,代码更简洁,错误提示更友好。对于新项目,FastAPI 是更现代的选择。
总结
通过本文,你已经掌握了 RESTful API 的核心设计原则,并用 Python(FastAPI)构建了一个完整的图书管理 API。RESTful 架构让 API 更易于理解、维护和扩展。下一步可以尝试连接真实数据库(如 SQLite、PostgreSQL),添加 JWT 认证,或部署到云服务器。