
后端GraphQL代码生成【免费下载链接】gqlgengo generate based graphql server library项目地址https://gitcode.com/gh_mirrors/gq/gqlgen点击查看免费下载本文以 gqlgen 仓库中的_examples/type-system-extension示例为主线讲解 GraphQL 类型系统扩展Type System Extensions的完整用法如何把 schema、type、interface、union、enum、input object、scalar 与字段级别的extend拆分到多个.graphql文件并结合自定义指令实现统一的日志切面。读完本文你将掌握用 gqlgen 组织多文件 Schema、使用extend语法增量扩展类型以及通过DirectiveRoot挂载指令实现的能力。什么是 Type System ExtensionsGraphQL 规范允许在定义类型系统的同时通过extend关键字对已有类型做“追加式”扩展而不必修改原始定义。它的典型价值在于模块化组织不同团队或模块可以各自维护一份扩展文件互不干扰增量演进在不动基础类型定义的前提下补充字段、指令、操作入口指令注入扩展的同时可以在新字段或类型上附加指令实现横切关注点日志、鉴权、限流等。本示例对应的规范章节是 GraphQL 规范的 Type System Extensions当前仓库 README 中给出的参考链接覆盖了schema、type、interface、union、enum、input object、scalar共七种可扩展对象外加通过extend type为对象增加新字段的场景。示例整体结构_examples/type-system-extension目录组织如下gqlgen.yml生成配置把./schemas/*.graphql全部作为 Schema 输入schemas/一个基础 Schema 文件加八个扩展文件generated.go、models_gen.go由go generate生成的可执行 Schema 与模型directive.go六个日志指令的实现resolver.go根 Resolver 与查询/变更实现server/server.goHTTP 服务入口。其中基础 Schema schemas/schema.graphql 定义了核心骨架schema { query: MyQuery } interface Node { id: ID! } type Todo implements Node { id: ID! text: String! state: State! } type MyQuery { todos: [Todo!]! } union Data Todo enum State { NOT_YET DONE }注意这里并没有定义MyMutation也没有Todo.verified字段——它们全部由后续的扩展文件补充。运行示例在仓库根目录执行$ go run ./_examples/type-system-extension/server/server.go 2018/10/25 12:46:45 connect to http://localhost:8080/ for GraphQL playground启动后打开http://localhost:8080/即可进入 GraphQL playground。用 curl 验证查询$ curl -X POST http://localhost:8080/query --data-binary {query:{ todos { id text state verified } }} {data:{todos:[{id:Todo:1,text:Buy a cat food,state:NOT_YET,verified:false},{id:Todo:2,text:Check cat water,state:DONE,verified:true},{id:Todo:3,text:Check cat meal,state:DONE,verified:true}]}}verified字段来自扩展文件这证明扩展后的 Schema 已被 gqlgen 正确合并并生成可执行代码。服务入口 server/server.go 支持通过环境变量PORT覆盖默认端口8080并同时注册了GET与POST两种 transport。逐类拆解七类扩展文件的写法1. schema 扩展补充 Mutation 入口与查询字段schemas/schema-extension.graphql 演示了最常用的一类扩展——给根类型追加操作入口extend schema { mutation: MyMutation } extend type MyQuery { todo(id: ID!): Todo } type MyMutation { createTodo(todo: TodoInput!): Todo! } input TodoInput { text: String! }extend schema { mutation: MyMutation }在原有只有query的 Schema 上新增mutation根操作extend type MyQuery为查询根类型追加todo(id: ID!)字段新增的MyMutation与TodoInput虽然是普通类型定义但通过上面的extend与根类型连接构成了完整的变更能力。对应的实现位于 resolver.goNewRootResolver()返回包含三条 Todo 数据的ResolverRootMyQuery()与MyMutation()分别返回queryResolver与mutationResolverCreateTodo会生成形如Todo:4的新 ID 并追加到内存切片中。2. type 扩展为对象追加字段schemas/type-extension.graphql 为Todo追加了布尔字段verified并挂上字段级指令directive fieldLogging on FIELD_DEFINITION extend type Todo { verified: Boolean! fieldLogging }由于verified是扩展字段gqlgen 会在模型生成时把它并入Todo结构体。从 resolver.go 可以看到内存中的三条 Todo 都直接给定了Verified值而模型文件 models_gen.go 中Todo结构体同时包含State、Text、Verified等字段。3. interface 扩展schemas/interface-extension.graphqldirective interfaceLogging on INTERFACE extend interface Node interfaceLogging该扩展不新增成员只给接口挂上interfaceLogging指令用于演示接口级别指令的声明与合并。4. union 扩展schemas/union-extension.graphqldirective unionLogging on UNION extend union Data unionLogging同样地仅为Data联合类型附加指令。5. enum 扩展schemas/enum-extension.graphqldirective enumLogging on ENUM extend enum State enumLogging枚举值NOT_YET、DONE本身没有变化扩展只为State附加指令。6. input object 扩展schemas/input-object-extension.graphqldirective inputLogging on INPUT_OBJECT extend input TodoInput inputLoggingTodoInput定义在 schema-extension 文件中这里通过extend input为它补充指令。生成代码中反序列化输入对象时会先检查ec.Directives.InputLogging是否实现未实现则返回 “directive inputLogging is not implemented” 错误见 generated.go 中unmarshalInputTodoInput相关逻辑。7. scalar 扩展schemas/scalar-extension.graphqldirective scalarLogging on SCALAR extend scalar ID scalarLoggingID是 GraphQL 内置标量通过extend scalar同样可以为其附加指令——这是对内置类型进行扩展的典型例子。指令驱动一个统一的日志切面上述七个文件里定义了六个指令enumLogging、fieldLogging、inputLogging、interfaceLogging、objectLogging、scalarLogging与unionLogging它们的实现都集中在 directive.go。以FieldLogging为例func FieldLogging(ctx context.Context, obj any, next graphql.Resolver) (res any, err error) { rc : graphql.GetFieldContext(ctx) log.Printf(field logging: %v, %s, %T, %v, rc.Path(), rc.Field.Name, obj, obj) return next(ctx) }要点指令函数签名统一为func(ctx context.Context, obj any, next graphql.Resolver) (res any, err error)next是原始解析器调用next(ctx)继续执行通过graphql.GetFieldContext(ctx)可取得当前字段上下文包括rc.Path()字段路径、rc.Field.Name字段名以及父对象obj每个指令都遵循“先打日志、再放行”的包装器模式因此查询时会按字段执行顺序输出多条日志便于追踪解析链路。指令的注册发生在 server/server.gosrv : handler.New( extension.NewExecutableSchema( extension.Config{ Resolvers: extension.NewRootResolver(), Directives: extension.DirectiveRoot{ EnumLogging: extension.EnumLogging, FieldLogging: extension.FieldLogging, InputLogging: extension.InputLogging, ObjectLogging: extension.ObjectLogging, ScalarLogging: extension.ScalarLogging, UnionLogging: extension.UnionLogging, }, }, ), )从 generated.go 的DirectiveRoot结构体可以看到gqlgen 为 Schema 中每个指令生成一个对应的函数字段若某个指令未在DirectiveRoot中赋值运行时会在对应位置直接返回 “directive xxx is not implemented” 错误。因此凡是 Schema 中声明过的指令都必须在这里提供实现这是 gqlgen 使用指令的一条硬性要求。生成配置与重新生成gqlgen.yml 内容如下schema: - ./schemas/*.graphql exec: filename: generated.go model: filename: models_gen.go关键点schema使用 glob 模式./schemas/*.graphql把基础文件与所有扩展文件一次性纳入合并范围——这正是多文件组织 Schema 的入口exec.filename指定生成的可执行 Schema含解析器调度、指令调用点输出到generated.gomodel.filename指定生成的 Go 模型输出到models_gen.go。重新生成代码的入口是 resolver.go 首行的//go:generate指令//go:generate go run ../../testdata/gqlgen.go在_examples/type-system-extension目录下执行go generate ./...gqlgen 会重新读取全部 Schema 文件并生成generated.go与models_gen.go。修改任何schemas/*.graphql文件后都需要重新生成扩展字段如verified才会反映到模型与执行代码中。扩展后的完整能力验证将基础 Schema 与所有扩展合并后最终得到的类型系统包含查询todos: [Todo!]!基础定义、todo(id: ID!): Todo扩展定义变更createTodo(todo: TodoInput!): Todo!扩展定义对象Todo在基础字段id、text、state之外获得扩展字段verified: Boolean!接口 / 联合 / 枚举 / 输入对象 / 标量均保留原始定义并通过extend附加了各自的日志指令。启动服务后除了本文开头演示的查询还可以调用扩展出的变更操作$ curl -X POST http://localhost:8080/query \ --data-binary {query:mutation { createTodo(todo: { text: \Buy a litter box\ }) { id text state verified } }}响应会返回形如{data:{createTodo:{id:Todo:4,text:Buy a litter box,state:NOT_YET,verified:false}}}的结果同时服务端日志会依次打印input object logging、object logging、field logging等记录直观展示指令切面在完整执行链路上的生效顺序。小结_examples/type-system-extension用一份基础 Schema 加八份扩展文件完整演示了 GraphQL Type System Extensions 在 gqlgen 中的落地方式extend schema补齐根操作extend type追加字段extend interface / union / enum / input / scalar为各类类型附加指令。结合DirectiveRoot统一注册指令实现可以在不修改原始类型定义的前提下为 Schema 注入日志等横切能力。这一模式非常适合需要多人协作、按模块拆分 Schema或希望保持核心类型稳定、通过增量扩展演进接口的 gqlgen 项目。延伸阅读示例配套的测试与更多配置可参考仓库中的 getting-started 与 config 文档指令定义与生成的完整细节可继续阅读本示例的 generated.go。赞分享后端GraphQL代码生成【免费下载链接】gqlgengo generate based graphql server library项目地址https://gitcode.com/gh_mirrors/gq/gqlgen点击查看免费下载相关推荐Relay Client Schema Extensions 完全指南用本地状态扩展 GraphQL Schema 的增删改查实战Relay Client Schema Extensions 完全指南用本地状态扩展 GraphQL Schema 的增删改查实战 Relay 不仅用于读写服前端开发工具gs-quant 从零到一卡尔曼滤波价差套利实战gs quant 从零到一卡尔曼滤波价差套利实战 2023 03 07铁矿石单日暴涨 4%螺纹钢 铁矿石的固定布林带价差策略直接打穿止损。把均值换成动态估后端数据库文档数据库DialoGPT-medium-joshua-openmind完整教程从模型下载到生成对话的简单步骤DialoGPT medium joshua openmind完整教程从模型下载到生成对话的简单步骤 DialoGPT medium joshua openm后端上一篇Cadence跨平台兼容性从x86到ARM架构的完整指南下一篇Make a README SEO优化策略如何让更多开发者发现您的项目创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考