API(Application Programming Interface)是不同软件系统之间的通信接口,是现代软件架构的核心组件。本文将从 基础概念到实际实现 ,详细讲解API开发的全流程。
一、API基础概念
1. 什么是API?
API是一组定义的规则和协议,允许一个软件系统与另一个软件系统交互,而无需了解其内部实现细节。
例如:
天气应用通过天气API获取实时天气数据
移动应用通过后端API与服务器通信
2. API的类型
REST API :基于HTTP协议,使用标准HTTP方法,是目前最流行的API类型
GraphQL API :允许客户端精确请求所需数据,减少网络传输
SOAP API :基于XML的重量级API,主要用于企业级应用
WebSocket API :提供双向实时通信,适合聊天、实时更新等场景
作者有话说:API开发一般都是WebAPI开发。
3. API核心原则
REST(Representational State Transfer)是一种API设计风格,遵循以下原则:
- 资源为中心 :使用URL表示资源(如 /users 、 /products/123 )
HTTP方法表示操作 :
GET :获取资源
POST :创建资源
PUT :更新资源
PATCH :部分更新资源
DELETE :删除资源
无状态 :每个请求都包含完整的状态信息,服务器不保存客户端状态
统一接口 :使用标准HTTP状态码和头信息
资源表示 :使用JSON或XML表示资源
二、HTTP请求格式
GET请求: 查询请求(get请求)一般请求体为空

四、HTTP响应格式
post请求:提交修改请求(隐秘数据修改post请求)一般加密;请求体一般不显示在URL中
\r\n\r\n:换行请求体和请求行中间一个空行
响应协议格式

回来流程:

五、API设计:规范与最佳实践
1. 设计流程
需求分析 :明确API的功能和使用场景
资源建模 :识别系统中的核心资源(如用户、产品、订单)
路径设计 :为每个资源定义清晰的URL路径
参数设计 :定义查询参数、路径参数和请求体
响应设计 :定义响应格式和状态码
认证授权 :设计安全机制
2. URL路径设计
使用复数名词 : /users 而非 /user
嵌套资源 :表示资源之间的关系,如 /users/123/orders
避免动词 :使用HTTP方法表示操作,而非URL中包含动词(如 /users/123 而非 /getUser/123 )
保持简洁 :避免过长或复杂的路径
URL:本质上是向服务器增删改查数据,多数是查协议://域名/路径?查寻参数
3. 请求与响应设计 请求设计
路径参数 :用于标识特定资源(如 /users/{id} )
查询参数 :用于过滤、排序和分页(如 /users?page=1&limit=10 )
请求体 :用于创建或更新资源,通常使用JSON格式
头信息 :用于传递元数据(如认证令牌、内容类型) 响应设计
- 使用标准HTTP状态码 :
200 OK:请求成功
201 Created:资源创建成功
204 No Content:请求成功但无响应体
400 Bad Request:请求格式错误
401 Unauthorized:未授权
403 Forbidden:禁止访问
404 Not Found:资源未找到
500 Internal Server Error:服务器内部错误
- 统一响应格式(字典内套字典) :
{
"status": "success",
"data": {...}, // 响应数据
"message": "请求成功"
}
错误响应 (字典内套字典又套列表):
{
"status": "error",
"error": {
"code": "INVALID_PARAMETER",
"message": "参数验证失败",
"details": [
{"field": "email", "message": "必须是有效的邮箱地址"}
]
}
}
返回两种格式:josn和HTML
josn:提供接口
HTML:提供给用户
4. 数据验证
请求参数验证 :确保传入的数据符合预期格式和约束
数据类型验证 :检查字符串、数字、日期等类型
业务规则验证 :检查数据是否满足业务逻辑要求(如邮箱唯一性)
六、API开发实现
1.什么是框架?
就相当于一个模版,我在这个模版上做一些修改。
2.下载框架
pip install fastapi uvicorn
3.代码撰写(用AI给你一个案例,现在按照我生成这个来演示)
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List
# 创建FastAPI应用实例对象
app = FastAPI(
title="简单FastAPI示例",
description="这是一个基础的FastAPI应用示例",
version="1.0.0"
)
# 定义数据模型
# 用户模型,(相当于强制数据类型)
class User(BaseModel):
name: str
id: int
email: str
# 示例:创建一个 users 列表,存放 User 模型实例
#模拟数据库
users_list = [
User(name="张三", id=1, email="zhangsan@example.com"),
User(name="李四", id=2, email="lisi@example.com"),
User(name="王五", id=3, email="wangwu@example.com"),
]
# 定义GET请求
# 获取所有用户
# 响应模型为 List[User],表示返回一个用户列表 返回的数据格式必须为 User 模型的格式
# 路径为 /users,HTTP 方法为 GET
# 函数 get_users 返回 users_list 列表
@app.get(path="/users",response_model=List[User])
def get_users():
return users_list
# 定义POST请求
# 创建用户
# 请求模型为 User,响应模型也为 User (提交的数据格式必须为 User 模型的格式)
# 路径为 /users,HTTP 方法为 POST
# 函数 create_users 接收一个 User 实例作为参数,将其添加到 users_list 列表中,并返回该实例
@app.post(path="/users",response_model=User)
def create_users(user:User):
users_list.append(user)
return user
# 定义PUT请求
# 更新用户
# 请求模型为 User,响应模型也为 User (提交的数据格式必须为 User 模型的格式)
# 路径为 /users/{user_id},HTTP 方法为 PUT
# 函数 update_users 接收一个 User 实例作为参数,将其添加到 users_list 列表中,并返回该实例
@app.put(path="/users/{user_id}",response_model=User)
def update_users(user_id:int,user:User):
for u in users_list:
if u.id == user_id:
u.name = user.name
u.email = user.email
return u
return {"error": "User not found"}
# 定义DELETE请求
# 删除用户
# 请求模型为 User,响应模型也为 User (提交的数据格式必须为 User 模型的格式)
# 路径为 /users/{user_id},HTTP 方法为 DELETE
# 函数 delete_users 接收一个 User 实例作为参数,将其从 users_list 列表中删除,并返回该实例
@app.delete(path="/users/{user_id}",response_model=User)
def delete_users(user_id:int):
for u in users_list:
if u.id == user_id:
users_list.remove(u)
return u
return {"error": "User not found"}
#服务器启动器
# 当直接运行该脚本时,启动 FastAPI 应用
# 监听主机为 127.0.0.1,端口为 8001
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8001)
4.运行展示

最下方为URL,点击链接跳转本地浏览器;

因为我们并没有在129.0.0.1:8000这个URL配置任何东西,使用对于fastapi这个模版会给你返回josn格式的
{ "detail": "Not Found" }
后台反馈:

下一步我们访问我们定义过的:127.0.0.1:8000/users

[
{
"name": "张三",
"id": 1,
"email": "zhangsan@example.com"
},
{
"name": "李四",
"id": 2,
"email": "lisi@example.com"
},
{
"name": "王五",
"id": 3,
"email": "wangwu@example.com"
}
]
后台反馈:

上面相当于运行代码的请求部分:

5.向服务器发送一个post请求
下面我们准备执行post操作,首先执行post我们的浏览器是不支持这种操作,需要借助三方工具:
postman;
因此我在网上找到一个在线工具: 在线Http接口调试工具 | 在线postman工具
下面是我代码的post请求设计:

以及接收数据格式:

在线工具页面:

操作重点:
1.将请求方式转换成post请求
2.输入对应URL及路径
3.选择application下的josn格式
4.数据格式必须按照定义的来
如图:

点击发送:
出现如下报错:

服务器端:

错误含义
OPTIONS /users :浏览器发送了一个OPTIONS类型的HTTP请求到/users端点
405 Method Not Allowed :服务器不允许使用OPTIONS方法访问该端点
作者提问:为什么会发生这个错误?
这是 CORS(跨域资源共享) 机制导致的:
当浏览器从一个域名(如 http://localhost:3000 )访问另一个域名(如http://127.0.0.1:8001)的API时
浏览器会先发送一个 预检请求(OPTIONS请求) 来检查服务器是否允许跨域访问
如果服务器没有配置CORS或没有处理OPTIONS请求,就会返回405错误
解决方案:在FastAPI中添加CORS支持
配置CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 允许所有来源,生产环境应限制具体域名
allow_credentials=True,
allow_methods=["*"], # 允许所有HTTP方法
allow_headers=["*"], # 允许所有请求头
)
配置说明
allow_origins : 指定允许的域名, ["*"] 表示允许所有域名
allow_credentials : 是否允许发送cookie
allow_methods : 指定允许的HTTP方法
allow_headers : 指定允许的请求头
效果:添加CORS中间件后:
浏览器的OPTIONS预检请求会得到正确响应
跨域请求(如从React/Vue前端调用API)会正常工作
不再出现405 Method Not Allowed错误
注意事项
在生产环境中,不要使用 allow_origins=["*"] ,应该指定具体允许的域名
只开放必要的方法和头信息,遵循最小权限原则
添加后并且导入相关库重启服务器:
from fastapi.middleware.cors import CORSMiddleware

ok,再次发送post请求:
postman出现如下报错:

服务器后台没有报错
应该是格式有问题,重新换格式,不要中文的双引号:

成功发送:

服务器后台没有变化:
咱们再次回到查询页面看数据是否提交给服务器

完美,perfect!!
6.向服务器发送一个删除请求delete
来到postman页面编辑URL地址为127.0.0.1:8001/users/1

点击发送
postman页面:

再用postman发送查询请求

点击发送

OK,数据(id=1的数据被删除)
7.向服务器发送一个修改的请求方式(put)
相应代码:

原始数据

我现在要把刘德华的邮箱改成888
打开postman将URL修改还有请求体

点击发送成功
再用postman查询可得

成功,perfect!!
8.咱们访问服务器的客户端有几个?
两个:
我们浏览器和postman这两个客户端
作者提问:还有吗,还有其他的方式访问我的服务器吗
我的服务器是可以分辨是什么客户端发的请求:在请求投头中有一参数:User-Agent:我是谁

如果你用爬虫,你能在User-Agent这个地方直接说我是扒手吗,所以爬虫需要伪装成浏览器对服务器发起请求获得自己想要的资源。
curl:可以向服务器发送请求(操作系统自带的)

作者提问:curl是否组包向服务器发包。
向终端输入:
url -i http://127.0.0.1:8000/users

返回了一个完整的响应命令:响应体+响应头+状态行
有点意思!
在终端用curl需要使用完整的请求包,详情请上网直接搜;
9.API文档
对于前后端分离:需要用API开发文档进行前后端数据交流。
之前手写,现在FastAPI提供API开发文档.

访问:

网址:http://127.0.0.1:8000/docs
http://127.0.0.1:8000/docs

简单FastAPI示例 - ReDoc
http://127.0.0.1:8000/redoc
可以直接在网站上进行数据请求,交互式的,就可以不用postman和curl。非常牛逼。
两个都可以直接用,不是所有的都有,这就是FastAPI目前这么受欢迎的原因。
七、面试习题
一、选择题
- 在Python中,哪个库用于构建API接口?
答案:D. 以上都是
- 以下哪个HTTP方法用于获取资源?
答案:A. GET
- 在FastAPI中,如何定义一个GET请求的路由?
答案:D. @app.get("/path")
- 在FastAPI中,如何获取请求的JSON数据?
答案:D. request.json()
- 以下哪个状态码表示请求成功?
答案:A. 200
二、判断题
- FastAPI是一个用于构建API接口的Python框架。(对/错)
答案:对
- 在FastAPI中,路由函数的返回值会自动转换为JSON格式。(对/错)
答案:对
- FastAPI支持自动生成OpenAPI文档。(对/错)
答案:对
- 在FastAPI中,@app.post("/path")用于定义一个POST请求的路由。(对/错)
答案:错,应为@app.post("/path")而不是@app.post("/path", methods=["POST"])
- FastAPI不支持异步编程。(对/错)
答案:错
三、简答题
- 简述FastAPI的优势和特点。
基于标准Python类型提示。
支持异步请求处理。
自动验证和文档(OpenAPI和JSON Schema)。
基于Starlette和Pydantic。
性能优异,与NodeJS和Go相当。
简单、快速、安全。
- 在FastAPI中,如何定义请求体的模型?
- 使用Pydantic模型定义请求体的结构,并使用`Body`参数从请求中提取数据。
示例代码:
from pydantic import BaseModel
from fastapi import FastAPI, HTTPException
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@app.post("/items/")
async def create_item(item: Item):
return item
- 如何在FastAPI中处理查询参数和路径参数?
- 使用函数参数和类型注解来定义路径参数和查询参数。
示例代码:
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
- 如何在FastAPI中进行请求数据的验证?
- 通过Pydantic模型自动验证请求数据,任何不符合模型的数据都会返回错误。
示例代码:
from pydantic import BaseModel, ValidationError
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
try:
item = Item(**data)
except ValidationError as e:
raise HTTPException(status_code=422, detail=e.errors())
- 简述FastAPI的依赖注入机制。
FastAPI允许使用依赖注入来处理请求前和请求后的逻辑,如认证、数据库会话等。
通过定义依赖函数并在路由函数中使用,可以重用代码并保持路由函数的简洁。
依赖可以被缓存,通过添加`Depends`来实现。
示例代码:
from fastapi import Depends, HTTPException
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/items/")
async def read_items(db: Session = Depends(get_db)):
items = db.query(Item).all()
return items