ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TypeGraphQL Schema SDL 生成指南:用 buildSchema 与 emitSchemaDefinitionFile 将 GraphQL Schema 导出为文件

TypeGraphQL Schema SDL 生成指南:用 buildSchema 与 emitSchemaDefinitionFile 将 GraphQL Schema 导出为文件 后端GraphQLAPI设计【免费下载链接】type-graphqlCreate GraphQL schema and resolvers with TypeScript, using classes and decorators!项目地址https://gitcode.com/gh_mirrors/ty/type-graphql点击查看免费下载TypeGraphQL 的核心特性是仅凭 TypeScript 的类与装饰器就能构建完整的 GraphQL schema但在实际工程中我们常常需要把 schema 打印为.gql/.graphql文件——用于客户端代码的自动补全与校验、作为 schema 回归测试的快照或直接阅读 SDL 文件来了解 API。本文围绕本仓库中 version-0.16.0 版文档 展开深入讲解 TypeGraphQL 提供的两种 schema 导出方式并结合当前仓库源码带你弄清emitSchemaFile三种取值形态、PrintSchemaOptions的排序配置、生成文件头警告以及目录自动创建等底层细节读完即可在自己的项目中落地 schema 文件自动生成与快照测试方案。为什么需要把 Schema 打印成 SDL 文件TypeGraphQL 的设计哲学是一切以类与装饰器为源头你用ObjectType、Field、Resolver、Query等装饰器描述类型与解析逻辑buildSchema在运行时读取装饰器收集的元数据metadata动态生成GraphQLSchema对象。schema 本身只存在于内存中不会以文本形式落盘。然而在很多场景下我们确实需要一个 SDLSchema Definition Language文本文件客户端工具链需要GraphQL 生态中大量工具如 Apollo CLI、GraphQL Code Generator、IDE 插件等依赖 schema SDL 文件实现查询的自动补全与校验回归检测快照把生成的 SDL 当作快照schema 一旦发生意外变更字段被删、类型被改快照对比就能第一时间发现回归直接阅读 API比起阅读复杂的 TypeGraphQL 业务代码或逐个在 GraphiQL / GraphQL Playground 中导航直接读一份 SDL 文件更直观、更方便评审与文档化。TypeGraphQL 为此提供了两条导出路径在buildSchema时自动输出或通过独立的工具函数编程式输出。方式一buildSchema 时自动输出 schema 文件最简单的方式是在调用buildSchema时传入emitSchemaFile选项。根据本仓库 buildSchema 源码该选项的类型定义如下emitSchemaFile?: string | boolean | EmitSchemaFileOptions;也就是说它支持三种形态分别对应三种使用方式const schema await buildSchema({ resolvers: [ExampleResolver], // 1. 布尔值自动在工作目录生成 schema 文件 emitSchemaFile: true, // 2. 字符串把 schema 写到指定路径与文件名 // emitSchemaFile: path.resolve(__dirname, snapshots/schema, schema.gql), // 3. 配置对象指定路径并微调打印格式 // emitSchemaFile: { // path: __dirname /schema.graphql, // sortedSchema: false, // 默认会按字母序排序输出 // }, });三种形态的具体语义如下取值行为true在**项目工作目录进程当前工作目录**根下生成 schema 文件。旧版0.16.0默认文件名为schema.gql当前仓库源码中默认文件名已改为schema.graphql即path.resolve(process.cwd(), schema.graphql)见 buildSchema.ts字符串路径将 schema 打印到该路径指向的文件例如path.resolve(__dirname, snapshots/schema, schema.gql)会把文件写到指定目录配置对象EmitSchemaFileOptions可同时指定path与sortedSchema打印选项若只传{}空对象则使用默认路径与默认打印选项当emitSchemaFile为真值时buildSchema在完成 schema 构建后会调用emitSchemaDefinitionFile将 SDL 写入文件再返回 schema 对象buildSchema.ts。这保证了构建即落盘——每次启动服务、每次构建schema 文件都会同步刷新。仓库中的 simple-usage 示例 就使用了字符串路径形态async function bootstrap() { const schema await buildSchema({ resolvers: [RecipeResolver], // Create schema.graphql file with schema definition in current directory emitSchemaFile: path.resolve(__dirname, schema.graphql), }); const server new ApolloServer({ schema }); const { url } await startStandaloneServer(server, { listen: { port: 4000 } }); console.log(GraphQL server ready at ${url}); }对应生成的 schema.graphql 文件开头会带有明确的生成文件警告头详见下文源码解析随后是完整的 SDL 内容包括Mutation、Query、Recipe类型、DateTimeISO标量以及字段描述与deprecated指令等。同步版本buildSchemaSync如果项目环境不方便使用异步 API例如某些启动脚本或需要同步执行的构建流程TypeGraphQL 还提供了buildSchemaSync用法完全一致但会同步写盘const schema buildSchemaSync({ resolvers: [ExampleResolver], emitSchemaFile: true, });在 buildSchema.ts 中它调用的是emitSchemaDefinitionFileSync二者底层共享同一套路径解析与打印选项逻辑。方式二编程式导出 emitSchemaDefinitionFile如果不想把导出逻辑耦合进buildSchema或者需要在任意时机如测试脚本、文件监听回调手动导出可以独立调用emitSchemaDefinitionFile及其同步版本emitSchemaDefinitionFileSync。二者都从 TypeGraphQL 的主入口导出见 utils/index.tsimport { emitSchemaDefinitionFile, buildSchema } from type-graphql; // ...省略业务代码 // 伪代码监听源码文件变化每次变更时重新导出 schema hypotheticalFileWatcher.watch(./src/**/*.{resolver,type,input,arg}.ts, async () { const schema getSchemaNotFromBuildSchemaFunction(); // 例如从 buildSchema 获取 schema await emitSchemaDefinitionFile(/path/to/folder/schema.gql, schema); });函数签名与默认行为emitSchemaDefinitionFile.tsemitSchemaDefinitionFile(schemaFilePath: string, schema: GraphQLSchema, options?: PrintSchemaOptions): Promisevoid emitSchemaDefinitionFileSync(schemaFilePath: string, schema: GraphQLSchema, options?: PrintSchemaOptions): void典型使用场景快照测试脚本在测试中构建 schema导出 SDL 到快照目录与已提交的快照对比任何 schema 变更都会导致测试失败——这正是 emit-schema-sdl 功能测试 所验证的核心能力本地开发自动生成配合chokidar、nodemon等文件监听工具在 resolver / type / input 文件变更时自动重写 schema 文件保证 IDE 与代码生成器始终拿到最新定义发布产物生成作为构建流水线的一步把 schema 文件输出到dist或文档目录。注意emitSchemaDefinitionFile接收的是已经构建好的GraphQLSchema对象因此它天然适用于任何 schema 来源——无论是 TypeGraphQL 的buildSchema产物还是其他工具生成的 schema。源码级解析打印选项、文件头与目录自动创建了解了两种用法后我们再深入到 emitSchemaDefinitionFile.ts 的实现看看导出文件背后的几个关键细节。PrintSchemaOptions控制输出排序export interface PrintSchemaOptions { sortedSchema: boolean; } export const defaultPrintSchemaOptions: PrintSchemaOptions { sortedSchema: true, };sortedSchema控制打印前是否对 schema 进行字典序排序true默认先调用lexicographicSortSchema(schema)对类型、字段按字母序重排再交给printSchema输出。排序后的文件更稳定多次构建内容一致非常适合作为快照对比false保持 schema 构建时的原始顺序输出。核心逻辑在getSchemaFileContent中function getSchemaFileContent(schema: GraphQLSchema, options: PrintSchemaOptions) { const schemaToEmit options.sortedSchema ? lexicographicSortSchema(schema) : schema; return generatedSchemaWarning printSchema(schemaToEmit); }这个选项既可以通过emitSchemaDefinitionFile的第三个参数传入也可以在buildSchema的emitSchemaFile配置对象中设置。从 buildSchema.ts 可以看到对象形态的选项会与默认值合并{ ...defaultPrintSchemaOptions, ...buildSchemaOptions.emitSchemaFile }因此只传{ path }时sortedSchema依然默认为true。生成的警告头导出的文件并非裸的 SDL而是自带一段警告注释# ----------------------------------------------- # !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! # !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! # -----------------------------------------------这段注释generatedSchemaWarningemitSchemaDefinitionFile.ts明确标识文件由 TypeGraphQL 自动生成、不应手工修改与源码中构建即覆盖的行为形成呼应。功能测试checkSchemaSDL也验证了输出内容必然包含THIS FILE WAS GENERATEDemit-schema-sdl.ts。自动创建缺失目录导出文件时如果目标目录尚不存在会不会报错不会。仓库通过 filesystem.ts 中的outputFile/outputFileSync辅助函数处理先尝试直接写文件若抛出ENOENT目录不存在错误则用mkdir(..., { recursive: true })递归创建目录后再写入。因此你可以放心把 schema 写到深层的新目录比如snapshots/schema/schema.gql无需提前手动建目录。功能测试 emit-schema-sdl.ts 对上述行为做了全面验证emitSchemaDefinitionFile/emitSchemaDefinitionFileSync写入文件成功含sortedSchema: false选项场景buildSchema/buildSchemaSync在指定路径、工作目录true、配置对象三种形态下均能正确生成文件排序开关的差异排序开启时descriptionProperty排在normalProperty之前关闭时则相反emit-schema-sdl.ts写入或建目录时若发生未知错误会如实抛出、不吞异常。实践建议与注意事项结合上文给出几条可直接落地的实践建议开发环境用trueCI/快照用配置对象。本地开发时emitSchemaFile: true即可让文件保持最新需要固定快照目录时用字符串路径或{ path: __snapshots__/schema/schema.graphql }指明位置默认保持排序输出。sortedSchema: true是默认值输出的字段顺序稳定适合作为快照若希望 SDL 顺序贴近代码声明顺序再关闭它快照测试与文件监听。将emitSchemaDefinitionFile接入测试脚本或 watcher配合git diff即可第一时间发现 schema 回归文件名差异。0.16.0 版文档示例中使用schema.gql当前仓库源码的默认文件名为schema.graphqlbuildSchema.ts指定字符串路径时按需自行选择即可自定义指令的限制。受graphql-js的printSchema限制TypeGraphQL 无法直接输出自定义指令到 SDL 文件。如果需要可以参考最新版 emit-schema 文档 中给出的方案自建一个基于第三方打印函数如graphql-tools/utils的printSchemaWithDirectives的导出函数再传入构建好的 schema 使用。总之无论你是想让 IDE 与客户端工具自动获得最新 schema还是想用快照守护 API 的稳定性TypeGraphQL 的emitSchemaFile与emitSchemaDefinitionFile系列 API 都提供了简洁而完整的解决方案配合本仓库的 功能测试 与 示例代码 可以快速验证所有行为。赞分享后端GraphQLAPI设计【免费下载链接】type-graphqlCreate GraphQL schema and resolvers with TypeScript, using classes and decorators!项目地址https://gitcode.com/gh_mirrors/ty/type-graphql点击查看免费下载相关推荐Prisma 生态中的 Schema 模块化graphql-import 跨文件导入与导出 GraphQL SDL 指南Prisma 生态中的 Schema 模块化graphql import 跨文件导入与导出 GraphQL SDL 指南 graphql import 是 P后端数据库GraphQLgraphql-codegen/schema-ast 插件完整指南从 GraphQL Schema 生成 SDL 文件的配置、源码与演进graphql codegen/schema ast 插件完整指南从 GraphQL Schema 生成 SDL 文件的配置、源码与演进 graphql开发工具prisma-generate-schema从 Prisma Datamodel SDL 自动生成 OpenCRUD GraphQL Schemaprisma generate schema从 Prisma Datamodel SDL 自动生成 OpenCRUD GraphQL Schema 导读 pr后端数据库GraphQL上一篇JiYuTrainer在极域电子教室中重获电脑控制权的终极方案下一篇如何实现GitHub下载10倍加速免费插件完整配置终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表