优化Strawberry GraphQL API性能:如何绕过PostgreSQL预格式化JSON的对象实例化?
解决方案
要绕过Strawberry的实例化和验证流程,直接返回预格式化的JSON数据,可采用以下几种实用方法:
方法1:自定义RawJSON标量(性能最优)
创建一个自定义JSON标量,让字段直接返回原始数据,完全跳过Strawberry的类型检查逻辑:
import strawberry from typing import Any # 定义自定义RawJSON标量,直接传递原始数据 @strawberry.scalar( serialize=lambda value: value, parse_value=lambda value: value, description="与GraphQL schema结构匹配的原始JSON数据" ) class RawJSON: pass # 修改查询字段的返回类型为RawJSON @strawberry.type class Query: @strawberry.field def teams_with_player(self, info) -> RawJSON: formatted_json = query_postgresql_for_formatted_json(info.selected_fields) return formatted_json
- 优势:完全绕过类型验证,性能损耗最低;
- 注意:必须确保数据库返回的结构严格匹配GraphQL Schema,否则会导致客户端接收异常数据。
方法2:为类型添加自定义序列化逻辑(保留类型提示)
为Strawberry类型添加serialize类方法,让它们直接处理原始字典,无需实例化类对象:
import strawberry @strawberry.type class Player: name: str age: int @classmethod def serialize(cls, value): # 直接返回原始字典,跳过实例化 return value @strawberry.type class Team: city: str players: list[Player] @classmethod def serialize(cls, value): # 递归处理嵌套的Player列表 value["players"] = [Player.serialize(p) for p in value["players"]] return value @strawberry.type class Query: @strawberry.field def teams_with_player(self, info) -> list[Team]: formatted_json = query_postgresql_for_formatted_json(info.selected_fields) return formatted_json
- 优势:保留GraphQL Schema的类型定义(客户端仍能看到
list[Team]类型),同时避免实例化开销; - 注意:嵌套字段需要手动处理序列化逻辑,确保层级结构正确。
方法3:全局禁用类型验证(不推荐)
通过Strawberry扩展全局跳过所有类型验证,适合完全信任数据库返回数据的场景:
from strawberry.extensions import Extension class SkipValidationExtension(Extension): def resolve(self, next_resolver, root, info, *args, **kwargs): # 直接执行解析器并返回原始结果,不进行类型检查 return next_resolver(root, info, *args, **kwargs) # 创建Schema时添加该扩展 schema = strawberry.Schema(Query, extensions=[SkipValidationExtension()])
- 优势:实现简单,无需修改现有类型或字段;
- 风险:全局禁用验证会导致所有字段失去类型检查,若数据结构异常无法提前发现。
内容的提问来源于stack exchange,提问作者Lionel Hamayon
相关产品推荐
相关产品推荐

