扫描二维码
关注或者微信搜一搜:编程智域 前端至全栈交流与成长
发现1000+提升效率与开发的AI工具和实用程序:https://tools.cmdragon.cn/
REST需要两次请求获取关联数据,而GraphQL通过嵌套查询单次获取,减少网络开销的同时避免数据冗余。
sequenceDiagram 客户端->>+ASGI服务器: POST /graphql ASGI服务器->>+GraphQL解析器: 解析查询语句 GraphQL解析器->>+数据加载器: 批量数据请求 数据加载器->>-数据库: 异步查询 数据库-->>数据加载器: 返回数据集 数据加载器-->>GraphQL解析器: 结构化数据 GraphQL解析器-->>ASGI服务器: JSON响应 ASGI服务器-->>客户端: HTTP 200
# 环境依赖:python3.11 fastapi==0.95.0 graphene==3.2.0 uvicorn==0.21.1
from graphene import ObjectType, String, Field, List
from pydantic import BaseModel
class UserModel(BaseModel):
id: int
name: str
email: str = None # 可选字段标注
class Query(ObjectType):
get_users = List(UserModel)
async def resolve_get_users(self, info):
# 模拟异步数据库查询
async def fetch_db():
return [{'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}]
raw_data = await fetch_db()
return [UserModel(**item) for item in raw_data]
from promise import Promise
from promise.dataloader import DataLoader
class UserLoader(DataLoader):
async def batch_load_fn(self, keys):
# keys是用户ID列表如[1,2,3]
async with AsyncSession() as session:
stmt = select(User).where(User.id.in_(keys))
result = await session.execute(stmt)
users = result.scalars().all()
user_map = {u.id: u for u in users}
return [user_map.get(k) for k in keys]
课后Quiz
问题:当GraphQL查询包含多层嵌套时,如何避免数据库查询风暴?
答案:采用DataLoader批量加载机制,通过缓存和请求合并技术。例如用户查询及其订单记录时,DataLoader会将所有需要的用户ID收集后执行单次IN查询,而非为每个用户单独查询。
常见报错解决方案
报错现象:
"message": "Cannot return null for non-nullable field User.email"
原因分析:
解决步骤:
required=True
标注预防建议:
class UserType(ObjectType):
email = String(required=False) # 显式声明可选性
余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
,阅读完整的文章:GraphQL为何能成为现代API开发的首选?
参与评论
手机查看
返回顶部