使用Go GqlGen实现GraphQL Interface时遭遇JSON反序列化错误
解决GqlGen中GraphQL Interface反序列化错误
错误根源
json: cannot unmarshal object into Go struct field Segment.segments.contents of type models.Content 这个错误的核心原因是:Go无法直接将JSON对象反序列化为接口类型(models.Content),因为接口本身没有具体结构,GqlGen需要明确知道如何将JSON映射到Content的具体实现类型(A或B)。
具体解决方案
1. 配置gqlgen.yml,注册接口实现
在项目根目录的gqlgen.yml中添加接口映射配置,告诉GqlGenContent接口的所有实现类型:
models: Content: # 注册Content接口的所有实现类型 implementations: - A - B # 指定对应的Go模型类型(根据实际包路径调整) model: github.com/shashank-sachan/graphql-interface-go/models.Content # 启用接口解析器 resolver: true
2. 实现Content接口的TypeResolver
在解析器文件(通常为resolver.go)中,为ContentResolver添加Type方法,用于识别具体的实现类型:
type ContentResolver struct{ Content models.Content } func (r *ContentResolver) Type() string { switch r.Content.(type) { case *models.A: return "A" case *models.B: return "B" default: panic("未知的Content类型") } }
3. 确保返回具体类型实例
在GetData的resolver逻辑中,返回的contents切片必须是具体类型(*models.A或*models.B)的实例,示例如下:
func (r *queryResolver) GetData(ctx context.Context) (*models.Root, error) { return &models.Root{ ID: "1", Title: "Test Root", Segments: []*models.Segment{ { ID: "s1", Contents: []models.Content{ &models.A{ID: "a1", Title: "Type A", Teams: []*models.Team{{Name: "Team 1"}}}, &models.B{ID: "b1", Title: "Type B", Score: 90}, }, }, }, }, nil }
4. 重新生成GqlGen代码
配置完成后,运行以下命令重新生成模型和解析器代码:
go run github.com/99designs/gqlgen generate
验证
重新启动服务后,执行GetData查询,即可正确返回包含A和B类型数据的结果,不再出现反序列化错误。
内容的提问来源于stack exchange,提问作者Shashank Sachan
相关产品推荐
相关产品推荐

