示例说明
Strawberry 的哲学是 schema 即类型注解:装饰器把普通类变成 GraphQL 类型,字段类型直接用 Python 注解表达,解析器就是普通方法——IDE 提示、类型检查全部生效。FastAPI 集成只需把 GraphQLRouter 挂到路径,与 REST 路由共存一个进程,REST 管运维端点、GraphQL 管聚合查询是常见分工。
技术要点
- 类型注解直接编译为 GraphQL schema
- 查询与变更分别用装饰器标记
- GraphQLRouter 与 REST 路由共存
代码解读
Book 类型用 strawberry.ID 标识符与标量字段;Query 的解析器按 ID 查内存书库,缺失返回 None 而非抛错;Mutation 解析器生成新 ID 插入并返回完整对象。末尾注释给出两条可在 GraphiQL 里直接执行的查询语句。
使用建议
上下文依赖注入用 context_getter 参数接入 FastAPI 的依赖体系。N+1 查询要配 dataloader 批量取数。解析器内错误按业务语义抛 GraphQLError。
代码示例
import strawberry
from fastapi import FastAPI
from strawberry.fastapi import GraphQLRouter
BOOKS = {'b-1': {'title': 'Designing Data', 'pages': 320}}
def get_books() -> dict:
return BOOKS
@strawberry.type
class Book:
id: strawberry.ID
title: str
pages: int
@strawberry.type
class Query:
@strawberry.field
def book(self, id: strawberry.ID) -> Book | None:
record = get_books().get(str(id))
if record is None:
return None
return Book(id=id, title=record['title'], pages=record['pages'])
@strawberry.type
class Mutation:
@strawberry.mutation
def add_book(self, title: str, pages: int) -> Book:
new_id = f'b-{len(get_books()) + 1}'
get_books()[new_id] = {'title': title, 'pages': pages}
return Book(id=new_id, title=title, pages=pages)
schema = strawberry.Schema(query=Query, mutation=Mutation)
app = FastAPI()
app.include_router(GraphQLRouter(schema), prefix='/graphql')
# GraphQL 查询示例:
# query { book(id: "b-1") { title pages } }
# mutation { addBook(title: "GraphQL in Prod", pages: 240) { id } }