strawberry + fastapi 是当前最轻量、类型安全且开发效率最高的组合,因其基于标准python类型注解,原生支持异步、pydantic集成与自动文档生成,而graphene依赖旧式类声明、类型提示弱、异步支持差。

直接用 Strawberry + FastAPI 是当前最轻量、类型安全且开发效率最高的组合,比 graphene 更贴合现代 Python 工程实践,尤其适合新项目。
为什么不用 graphene 而选 Strawberry?
graphene 仍被广泛使用,但其设计基于旧式类声明(如继承 graphene.ObjectType),类型提示支持弱,对异步解析器、泛型、Pydantic 集成等现代特性支持滞后。而 Strawberry 完全基于标准 Python 类型注解,和 FastAPI 共享同一套类型系统,自动推导输入/输出结构、文档、验证逻辑。
常见踩坑点:
-
graphene的resolve_*方法签名不一致,容易漏传info或误用context -
graphene默认不支持原生async def解析器,需额外包装;Strawberry直接支持async字段函数 -
graphene的 schema 导出为 SDL 时需手动调用schema.introspect(),而Strawberry可直接用strawberry.print_schema(schema)
如何定义带参数的 Query 和嵌套字段?
GraphQL 的核心价值在于“按需获取”,所以字段必须能接收参数、返回可展开的子结构。在 Strawberry 中,这通过类型注解 + @strawberry.field 实现,无需额外 resolver 命名约定。
实操要点:
- 参数直接写在方法签名里,类型必须明确(如
id: str或limit: int = 10) - 嵌套对象字段只需返回对应类型实例(或
list),框架自动递归解析 - 非空字段用
strawberry.ID!或int!表示,对应 SDL 中的!后缀
示例:
@strawberry.type
class Post:
id: strawberry.ID
title: str
author_id: int
<p>@strawberry.type
class User:
id: strawberry.ID
name: str
posts: list[Post] # 自动触发 Post 字段解析</p><p>@strawberry.type
class Query:
@strawberry.field
def user(self, id: strawberry.ID) -> User:</p><h1>这里可同步或异步查库</h1><pre class="brush:php;toolbar:false;"><code> return User(id=id, name="Alice", posts=[Post(id="1", title="Hello", author_id=1)])</code>
怎么避免 N+1 查询问题?
N+1 是 GraphQL 最典型的性能陷阱:查 1 个用户,再为每个用户的每篇文章单独查作者,变成 1+N 次 DB 请求。关键不是“禁用嵌套”,而是把数据加载逻辑从 resolver 内部移出,统一由 DataLoader 批处理。
建议做法:
- 不要在
Post.authorresolver 里直接调db.get_user(post.author_id) - 改用
aiodataloader(异步友好)或自建简易 batch loader,将所有待查author_id收集后一次查库 - loader 实例应挂载在
context上,确保单次请求内复用(context["user_loader"]) -
Strawberry的get_context回调可用于初始化 loader
错误写法:
def resolve_author(self, info, post):
return db.get_user(post.author_id) # 每个 post 触发一次查询
如何暴露 Mutation 并校验输入?
Mutation 不是“加个 class Mutation”就完事。真实场景中,输入往往含多层嵌套、必填约束、格式校验(如邮箱、长度),这些靠手写 if 判断既易错又难维护。
推荐路径:
- 用
strawberry.input定义输入类型,支持嵌套、默认值、Optional标记 - 结合
pydantic.BaseModel做深度校验(例如邮箱正则、字符串最小长度),再用strawberry.experimental.pydantic.input转换 - Mutation 方法签名直接接收该 input 类型,类型检查 + 文档 + 校验全部自动完成
注意:strawberry 默认不拦截 Pydantic 错误,需在 get_context 或中间件中捕获 ValidationError 并转为 GraphQL 错误格式。
真正难的从来不是“怎么写第一个 Query”,而是当 User 关联 Profile、Settings、Notifications,且每个都有权限控制、分页、缓存策略时,如何让 schema 可读、resolver 可测、错误可追踪——这些细节不会出现在“Hello World”例子里,但会决定半年后你是否想重写整个 API 层。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











