目录
[2.2、基础示例:简单 POST 接口](#2.2、基础示例:简单 POST 接口)
[1. 基础配置与数据结构](#1. 基础配置与数据结构)
[2. 核心验证逻辑](#2. 核心验证逻辑)
[3. 接口实现](#3. 接口实现)
[(1)注册接口 /user/register](#(1)注册接口 /user/register)
[(2)登录接口 /user/login](#(2)登录接口 /user/login)
[(3)信息查看接口 /user/logout](#(3)信息查看接口 /user/logout)
[4. 服务启动配置](#4. 服务启动配置)
1、前置知识
1.1、什么是HTTP请求方式
HTTP 请求方式(也叫 "HTTP 方法")是客户端(浏览器、App、Postman 等)向服务器发送请求时,附带的 "操作指令"。
类比:你去银行办理业务,会先告诉柜员 "我要查余额""我要存钱""我要改手机号""我要注销账户"------ 这些指令就对应 HTTP 的 4 种核心请求方式,服务器根据指令执行不同操作。
核心原则:
- 每种请求方式都有明确的 "业务语义",不能混用;
- 服务器会根据 "路径 + 请求方式" 识别唯一接口(比如GET /user/1 和POST /user/1是两个不同接口)。
请求方式:
- **GET:**查数据(无请求体,用路径 / 查询参数);
- **POST:**创数据(有请求体,传复杂 / 敏感数据);
- **PUT:**改数据(有请求体,全量覆盖);
- **DELETE:**删数据(用路径参数传标识);
1.2、GET和POST请求方式
仅需掌握的 2 种核心请求方式(GET/POST)
在实际开发中,最常用的 HTTP 请求方式只有 2 种 ------GET(查询) 和POST(提交),完全能覆盖大部分业务场景(比如查询数据、用户注册、提交表单等)。
1、GET:查询数据("查")
核心作用
从服务器"获取"数据,不会修改服务器上的任何内容(只读操作)。
数据传递方式
通过 URL路径 或 查询参数 传参(数据会暴露在URL中)。
适用场景
- 商品列表查询、用户详情查询、搜索功能;
- 不需要提交复杂/敏感数据的场景。
- 路径传参或查询参数
2、POST:提交数据("增/提交")
核心作用
向服务器"提交"数据,通常用于创建新资源(比如注册用户)或提交表单(比如登录、下单)。
数据传递方式
通过 请求体 传参(数据隐藏在HTTP请求中,不暴露在URL里)。
适用场景
- 用户注册、登录、提交订单;
- 传递密码、多字段表单、复杂数据(比如嵌套信息)等敏感/复杂内容。
3、核心区别
|------|-------------|----------------|
| 对比维度 | GET(查) | POST(提交) |
| 核心作用 | 从服务器拿数据(只读) | 向服务器送数据(修改/创建) |
| 数据位置 | 暴露在URL中 | 隐藏在请求体中 |
| 敏感数据 | 不适合(URL暴露) | 适合(隐藏安全) |**GET:**URL 传数据,公开、幂等、有大小限制,适合获取数据;
**POST:**请求体传数据,私密、非幂等、无大小限制,适合提交数据。
4、注意点
- GET方法不能带请求体(HTTP规范),想传请求体就用POST;
- 密码、手机号等敏感数据,必须用POST(请求体)传递,不能用GET;
- 接口标识是"路径+请求方式":
GET /users和POST /users是两个不同接口,不会冲突。- 通过浏览器地址栏只能访问使用GET方法的接口
2、POST请求
2.1、核心概念
- POST 方法 :用于向服务器提交数据(如表单提交、创建资源),数据放在请求体(而非 URL 中),支持大量数据传输,更安全。
- JSON 响应 :FastAPI 会自动将 Python 字典/列表序列化为 JSON 格式,响应头默认设为
application/json(无需手动配置)。- 请求体:POST 请求的核心数据载体,FastAPI 优先解析 JSON 格式的请求体。
2.2、基础示例:简单 POST 接口
1、代码实现
创建文件 main.py
pythonfrom fastapi import FastAPI # 初始化 FastAPI 应用 app = FastAPI() # 定义 POST 接口:路径为 /add @app.post("/add") def add_numbers(data: dict): # data 接收 JSON 请求体(自动解析为 Python 字典) # 从请求体中获取参数(需自行处理参数缺失/类型错误) a = data.get("a") b = data.get("b") # 简单校验参数 if not (isinstance(a, (int, float)) and isinstance(b, (int, float))): return {"code": 400, "message": "参数 a/b 必须是数字", "data": None} # 业务逻辑:两数相加 result = a + b # 返回 JSON(直接返回字典,FastAPI 自动序列化) return { "code": 200, "message": "成功", "data": {"sum": result} }
2、运行与测试
- 启动服务器:
bashuvicorn main:app --reload
- 访问调试界面:浏览器打开 **http://127.0.0.1:8000/docs**(FastAPI 自动生成的 Swagger UI)。
- 测试步骤:
- 找到 /add****接口 ,点击Try it out。
输入 JSON 请求体(示例):
{"a": 10, "b": 20}
点击Execute
- 查看响应结果(JSON 格式):
3、关键说明
- 请求体解析 :
data: dict表示接收 JSON 格式的请求体,FastAPI 自动将 JSON 字符串转为 Python 字典。- JSON 响应 :返回值为 Python 字典时,FastAPI 自动设置响应头
Content-Type: application/json,并序列化字典为 JSON 字符串。- 手动校验问题:上述代码需手动校验参数类型/缺失,不够优雅------下一节将用 Pydantic 模型解决。
3、request对象
在实际开发过程中,有些时候我们需要通过Request对象直接获取⼀些信息,如:我们希望获取客户端的
IP等信息,此时我们在路由操作函数中直接定义类型为Request的对象参数,就可以在代码中使⽤
Request对象进⾏数据的获取。
假设在路由函数中定义了request:Request,那么该对象可以获取到哪些信息呢?
|------------------------|-------------------------------|
| 操作 | 说明 |
| request.client.host | 客户端连接的host |
| request.client.port | 客户端连接的端口号 |
| request.method | 请求方法 |
| request.base_url | 请求路径(注:通常base_url指请求的基础URL) |
| request.headers | 请求头信息 |
| request.cookies | 请求携带的Cookie |
| request.url | 完整请求URL |
| request.url.components | URL的各组成部分 |
| request.url.scheme | 请求使用的协议(如http/https) |
| request.url.hostname | 请求的host地址 |
| request.url.port | 请求的端口号 |
| request.url.path | 请求的路径部分 |
| request.url.query | 请求的URL查询参数 |
| request.path_params | 请求的路径参数(如/user/{id}中的id) |
| request.query_params | 请求的URL查询参数 |
| request.form() | 读取请求中的表单数据 |
| request.json() | 解析请求中的JSON数据 |
| request.body() | 读取原始请求体(字节类型) |
4、基于FastAPI的用户接口设计与爬虫测试实践
在Web开发中,接口是前后端交互的核心,而接口测试则是保障服务稳定性的关键环节。本文将通过一个简单的用户注册登录系统为例,介绍如何使用FastAPI快速搭建接口服务,并结合Python爬虫技术(requests库)进行接口测试,完整展示从接口开发到功能验证的全过程。
4.1、技术栈选择
本次实践涉及的核心技术如下:
- FastAPI:一款高性能的Python Web框架,支持自动生成API文档,便于快速开发RESTful接口
- requests:Python中最常用的HTTP请求库,可模拟浏览器发送请求,常用于接口测试和爬虫开发
- 正则表达式:用于对用户名和密码进行格式验证
- uvicorn:异步ASGI服务器,用于运行FastAPI应用
4.2、接口服务设计与实现
我们首先搭建一个包含用户注册、登录和信息查看功能的接口服务,核心代码如下:
1. 基础配置与数据结构
pythonimport uvicorn from fastapi import FastAPI, Request import re # 实例化FastAPI应用(注意:原代码缺失此行,实际开发需补充) app = FastAPI() # 模拟用户数据库(实际项目中应使用数据库存储) user_datas = [ { "username": "admin123", "password": "admin_123", } ]
2. 核心验证逻辑
为保证用户信息规范性,我们设计了用户名和密码的验证规则:
- 用户名长度需大于6位
- 密码需同时包含数字、字母、下划线,且长度至少9位
pythondef judgment(username, password): """验证用户名和密码格式是否符合要求""" # 密码正则:包含数字(?=.*\d)、字母(?=.*[a-zA-Z])、下划线(?=.*_),总长度9位以上 if len(username) > 6 and re.match(r'^(?=.*\d)(?=.*[a-zA-Z])(?=.*_)[a-zA-Z0-9_]{9,}$', password): return 1 # 验证通过 else: return 0 # 验证失败
3. 接口实现
(1)注册接口
/user/register功能:接收用户名和密码,验证格式并检查用户名唯一性,成功则添加到用户列表
python@app.post('/user/register') def register(request: Request): # query_params 是 Request 对象的属性,用于获取 URL 中的查询参数(键值对形式) username = request.query_params['username'] password = request.query_params['password'] # 检查用户名是否重复 for user in user_datas: if user['username'] == username: return {"result": "注册失败:用户名重复"} # 验证格式并注册 if judgment(username, password): user_datas.append({"username": username, "password": password}) return {"result": f"注册成功:{username}成功注册"} else: return {"result": "注册失败:注册的用户名和密码未满足要求"}(2)登录接口
/user/login功能:验证用户凭据,成功则返回登录信息,失败则提示错误原因
python@app.post('/user/login') def login(request: Request): username = request.query_params['username'] password = request.query_params['password'] if judgment(username, password): for user in user_datas: if user['username'] == username and user['password'] == password: return {'result': f"登录成功:{username}欢迎"} return {"result": "登录失败:用户名或密码错误"} else: return {'result': '登录失败:用户名或密码输入不正确'}(3)信息查看接口
/user/logout功能:返回当前系统中所有用户信息
python@app.get('/user/logout') def logout(): return {"massage": f"{user_datas}"}
4. 服务启动配置
pythonif __name__ == '__main__': # 启动uvicorn服务器,监听本地8000端口 uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)
4.3、接口测试脚本开发(基于requests)
为验证接口功能,我们使用requests库开发一个交互式测试脚本,模拟用户操作流程:
测试脚本核心逻辑:
python# 导入 requests 库:用于发送 HTTP 请求(与 FastAPI 后端接口通信) import requests # 定义后端接口 URL 列表:按顺序对应 注册、登录、退出 接口 # 注意:原代码中 "查看" 功能调用的是 logout 接口(URLs[2]),存在逻辑不一致,后续需修正 urls = [ 'http://127.0.0.1:8000/user/register', # 索引0:用户注册接口 'http://127.0.0.1:8000/user/login', # 索引1:用户登录接口 'http://127.0.0.1:8000/user/logout', # 索引2:用户退出接口(原代码误用于"查看"功能) ] # 无限循环:持续接收用户操作,直到用户选择"4、退出" while True: # 显示操作菜单,获取用户输入(strip() 去除输入前后空格,避免误触发) user_input = input('1、注册\n2、登录\n3、查看\n4、退出\n请输入你要进行的操作:').strip() # 分支1:用户选择"1、注册" if user_input == '1': # 接收用户输入的用户名和密码(用于注册) user = input("用户名:").strip() password = input("密码:").strip() # 发送 POST 请求到注册接口: # 注意:这里用 params 传递参数(参数会拼在 URL 上),不符合接口规范! # 推荐改为 json 参数(JSON 格式请求体):json={"username":user,"password":password} res = requests.post( url=urls[0], # 目标接口:注册接口 params={"username": user, "password": password} # 传递注册参数(URL参数方式,不推荐) ) # 解析响应结果:后端返回 JSON 格式,用 json() 转为 Python 字典 result = res.json() # 打印响应中的 "result" 字段(假设后端返回格式包含该字段) print(f"注册结果:{result['result']}") # 分支2:用户选择"2、登录" elif user_input == '2': # 接收用户输入的用户名和密码(用于登录) user = input("用户名:").strip() password = input("密码:").strip() # 发送 POST 请求到登录接口: # 同样问题:用 params 传递参数(URL参数),不推荐,应改为 json 参数 res = requests.post( url=urls[1], # 目标接口:登录接口 params={"username": user, "password": password} # 传递登录参数(URL参数方式,不推荐) ) # 解析 JSON 响应 result = res.json() # 打印登录结果(后端返回的 "result" 字段) print(f"登录结果:{result['result']}") # 分支3:用户选择"3、查看" elif user_input == '3': # 发送 GET 请求: # 关键问题:原代码调用的是 logout 接口(URLs[2]),与"查看"功能不匹配! # 需修正为专门的查看接口(如 'http://127.0.0.1:8000/user/list') res = requests.get(url=urls[2]) # 错误:用退出接口实现查看功能,逻辑矛盾 # 解析 JSON 响应 result = res.json() # 打印响应中的 "massage" 字段:注意拼写错误(应为 "message"),需与后端返回字段一致 print(f"查看结果:{result['massage']}") # 分支4:用户选择"4、退出" elif user_input == '4': print("退出程序...") break # 终止无限循环,退出程序 # 其他输入:无效操作 else: print("输入的操作错误,请重新输入(仅支持 1-4)!")通过本次实践,我们完整走通了"接口开发→功能测试"的流程。FastAPI的高效开发特性与requests的便捷请求能力相结合,为小型项目的接口验证提供了简单实用的解决方案。




