Strawberry GraphQL自定义扩展开发指南
概述
Strawberry GraphQL框架提供了强大的扩展机制,允许开发者在GraphQL执行流程的不同阶段插入自定义逻辑。本文将深入探讨如何创建和使用自定义扩展,以及扩展的各种应用场景。
扩展基础
创建基本扩展
要创建自定义扩展,需要继承SchemaExtension
基类:
from strawberry.extensions import SchemaExtension
class BasicExtension(SchemaExtension):
def get_results(self):
return {"custom_data": "扩展返回的附加数据"}
创建Schema时通过extensions
参数添加扩展:
schema = strawberry.Schema(query=Query, extensions=[BasicExtension])
核心扩展点
解析器拦截
resolve
方法允许在所有解析器执行前后插入逻辑:
class ResolveLogger(SchemaExtension):
def resolve(self, _next, root, info, *args, **kwargs):
print(f"即将解析字段: {info.field_name}")
result = _next(root, info, *args, **kwargs)
print(f"字段解析完成: {info.field_name}")
return result
注意:
- 必须将所有参数传递给
_next
调用 - 支持异步实现
- 如需针对特定字段,应考虑使用字段级扩展
结果处理
get_results
方法允许向GraphQL响应中添加额外数据:
class MetricsExtension(SchemaExtension):
def __init__(self):
self.query_count = 0
def get_results(self):
return {"metrics": {"query_count": self.query_count}}
生命周期钩子
Strawberry提供了细粒度的生命周期钩子,采用生成器语法实现:
操作级别钩子
class OperationTimer(SchemaExtension):
def on_operation(self):
start_time = time.time()
yield
duration = time.time() - start_time
print(f"操作耗时: {duration}秒")
验证阶段钩子
class ValidationLogger(SchemaExtension):
def on_validate(self):
print("开始验证查询")
yield
print("验证查询完成")
解析阶段钩子
class ParseMonitor(SchemaExtension):
def on_parse(self):
print("开始解析查询文档")
yield
print("解析查询文档完成")
执行阶段钩子
class ExecutionTracker(SchemaExtension):
def on_execute(self):
print("开始执行查询")
yield
print("查询执行完成")
高级应用场景
错误格式扩展
class ErrorFormatter(SchemaExtension):
def on_operation(self):
yield
result = self.execution_context.result
if getattr(result, "errors", None):
result.errors = [
StrawberryGraphQLError(
extensions={"timestamp": datetime.now().isoformat()},
nodes=error.nodes,
message=f"处理出错: {error.message}",
)
for error in result.errors
]
查询缓存实现
query_cache = {}
class QueryCache(SchemaExtension):
def on_execute(self):
ctx = self.execution_context
cache_key = f"{ctx.query}:{json.dumps(ctx.variables)}"
if cache_key in query_cache:
ctx.result = query_cache[cache_key]
yield
if cache_key not in query_cache:
query_cache[cache_key] = ctx.result
请求拦截
class QueryBlocker(SchemaExtension):
def on_execute(self):
if self.execution_context.operation_name == "RestrictedQuery":
self.execution_context.result = GraphQLExecutionResult(
data=None,
errors=[GraphQLError("该操作已被限制")],
)
return
yield
执行上下文访问
扩展可以访问丰富的执行上下文信息:
class DBConnectionExtension(SchemaExtension):
def on_operation(self):
ctx = self.execution_context
ctx.context["db"] = Database.get_session()
yield
ctx.context["db"].close()
可用的上下文属性包括:
query
: 原始GraphQL查询字符串variables
: 查询变量operation_name
: 操作名称context
: 请求上下文对象result
: 执行结果
最佳实践
- 性能考虑:扩展中避免耗时操作,必要时使用异步
- 错误处理:确保扩展中的异常不会中断整个GraphQL流程
- 职责单一:每个扩展应专注于单一功能
- 可测试性:设计可独立测试的扩展组件
- 文档记录:为自定义扩展编写清晰的文档说明
通过合理使用扩展机制,可以极大地增强Strawberry GraphQL的功能性和灵活性,满足各种定制化需求。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考