GraphQL 备忘清单Schema 定义、查询与变更Mutations速查指南【免费下载链接】reference面向开发者的技术速查清单Cheat Sheets集合整理常见技术、工具与开发流程帮助快速查阅关键信息提高开发效率。项目地址: https://gitcode.com/GitHub_Trending/referen/reference本篇技术指南基于 Quick Referencereference仓库中的 GraphQL 备忘清单 编写围绕 GraphQL 的核心概念展开从 Schema 中的标量类型、类型定义、类型修饰符到查询Query、变更Mutation、片段Fragment、变量Variables与指令Directives的完整语法。读完本文你可以直接对照速查表写出规范的 GraphQL 类型定义与查询语句并理解每一类语法在 API 设计中的作用。一、GraphQL 是什么GraphQL 是为 RESTful API 提供的一种替代方案它的核心特征包括GraphQL 是一种 API 查询语言客户端通过该语言直接描述“需要哪些数据”而不是被动接受服务端固定端点返回的结构使用清晰的共享术语描述 API 的形状Schema 即契约客户端与服务端围绕同一套类型定义协作客户端发出查询/突变以读取和更新数据读操作叫query写操作叫mutation两者语法相似、职责不同语法可以表达复杂的实体关系嵌套字段即可遍历关联实体无需为每种组合单独设计端点多语言生态GraphQL 有各种编程语言实现的客户端与服务端库可与任意技术栈配合使用。在 README.md 的首页导航中这份清单位于“编程”分区与 Bash、Python、TypeScript 等速查表并列是开发者在编写 GraphQL 相关代码时随时翻阅的参考资料。二、Schema 四大操作类型Schema 是 GraphQL API 的骨架共涉及四类操作操作作用query读取和遍历数据mutation修改数据或触发动作subscription当发生事件时运行查询query与mutation是日常使用最频繁的两类前者只读、可重复执行后者产生副作用例如创建评论、更新用户资料。subscription则面向实时场景由事件驱动、按需推送数据。三、内置标量类型GraphQL 提供五个内置标量所有 Schema 类型定义都建立在这些基础值类型之上标量含义Int有符号 32 位整数Float有符号双精度浮点值StringUTF-8 字符序列Boolean对或错布尔值类型ID唯一标识符注意两点Int的取值受 32 位有符号整数范围限制超出范围时应使用Float或String表达ID与String序列化后同为字符串但语义上专用于标识实体如用户 ID、订单号便于区分“数据”与“引用”。四、类型定义系统GraphQL 的类型系统由六种定义构成关键字定义类型scalar标量类型type对象类型interface接口类型union联合类型enum枚举类型input输入对象类型其中type描述服务端可返回的数据结构input描述客户端可提交的数据结构二者不可混用——这是 GraphQL 类型系统中“输出类型”与“输入类型”分离的设计。类型修饰符空值语义是否允许null由类型后缀表达这是 GraphQL Schema 中最容易写错的部分写法含义String可空字符串String!非空字符串[String]可空字符串列表[String]!可空字符串的非空列表[String!]!非空字符串的非空列表关键在于外层与内层感叹号的独立性[String!]!表示“列表本身一定存在且列表中每个元素都非空”而[String]!仅保证列表存在元素仍可为null。设计接口时应明确每一层的空值承诺客户端才能据此省略空值判断。五、输入参数与默认值字段可以接受参数速查表中以users查询为例演示了参数的四种演进形式基本输入type Query { users(limit: Int): [User] }带默认值的输入type Query { users(limit: Int 10): [User] }多个参数type Query { users(limit: Int, sort: String): [User] }多个参数加默认值type Query { users(limit: Int, sort: String asc): [User] } type Query { users(limit: Int 10, sort: String asc): [User] }默认值的意义在于调用方可以只传关心的参数其余走默认行为如默认分页大小 10、默认升序排序同时保留完整参数集供高级调用。输入对象类型当参数变多时用input类型把它们聚合为一个对象可读性与向后兼容性都更好input ListUsersInput { limit: Int since_id: ID }type Mutation { users(params: ListUsersInput): [User]! }注意返回类型[User]!使用了非空列表修饰符——承诺调用一定返回一个可能为空的列表而不是null。六、自定义标量内置标量不足以表达领域值时如 URL、日期时间、IP 地址可以声明自定义标量scalar Url type User { name: String homepage: Url }scalar Url只是声明类型存在其解析序列化为 JSON、从 JSON 解析回内部值由具体语言的服务端实现负责。不同实现库对自定义标量的序列化约定可能不同跨团队协作时应明确其 wire 格式。七、接口Interface接口用于抽取多个对象类型的公共形状一个对象可以实现一个或多个接口interface Foo { is_foo: Boolean } interface Goo { is_goo: Boolean } type Bar implements Foo { is_foo: Boolean is_bar: Boolean } type Baz implements Foo, Goo { is_foo: Boolean is_goo: Boolean is_baz: Boolean }在这个例子中Bar实现FooBaz同时实现Foo和Goo。客户端可以针对接口编写查询不必关心具体实现类型后续新增实现类型也不会破坏既有查询。八、联合Union联合是“一个字段可能返回多种对象”的另一种表达方式它不要求这些对象共享字段type Foo { name: String } type Bar { is_bar: String } union SingleUnion Foo union MultipleUnion Foo | Bar type Root { single: SingleUnion multiple: MultipleUnion }SingleUnion只有一个成员MultipleUnion由Foo | Bar构成。接口与联合的区别在于接口的成员必须共享接口字段联合的成员之间没有任何共同形状——当返回类型“毫无共性”时更适合用联合。九、枚举Enum枚举把字段限定在一组已知取值内既约束了输入也描述了输出enum USER_STATE { NOT_FOUND ACTIVE INACTIVE SUSPENDED } type Root { stateForUser(userID: ID!): USER_STATE! users(state: USER_STATE, limit: Int 10): [User] }这里体现了枚举的双向用途stateForUser的返回类型USER_STATE!承诺结果必为四个状态之一users的参数state则只接受这些取值或可空时接受缺省非法状态会在执行前被类型检查拦截。十、查询Query语法以下是速查表中基于 Star Wars 示例 Schema 的一组完整查询练习每个示例都附带真实执行结果可直接对照验证。基本字段查询{ hero { name } }结果{ data: { hero: { name: R2-D2 } } }查询体本身不需要query关键字——最简形式就是大括号包裹的字段选择集。所有响应都包裹在data键之下。注释查询中可以写注释以#开头便于阅读与协作{ hero { name # 查询可以有注释 friends { name } } }结果{ data: { hero: { name: R2-D2, friends: [ { name: Luke Skywalker }, { name: Han Solo } ] } } }参数Arguments给字段传参用字段名(参数: 值)的形式{ human(id: 1000) { name height } }结果{ data: { human: { name: Luke Skywalker, height: 1.72 } } }不同类型的参数值参数值除了字符串、整数等标量字面量还可以是枚举值{ human(id: 1000) { name height(unit: FOOT) } }结果单位换算为英尺{ data: { human: { name: Luke Skywalker, height: 5.6430448 } } }同一字段通过参数切换行为米/英尺是“用一个端点覆盖多种输出”的典型用法。别名Aliases当同一字段需要以不同参数调用多次时别名可以避免结果键名冲突{ empireHero: hero(episode: EMPIRE) { name } jediHero: hero(episode: JEDI) { name } }结果中两个结果分别挂在empireHero与jediHero键下{ data: { empireHero: { name: Luke Skywalker }, jediHero: { name: R2-D2 } } }片段Fragments片段把可复用的字段选择集定义出来用...片段名引入避免同一组字段在多个位置重复书写{ leftComparison: hero(episode: EMPIRE) { ...comparisonFields } rightComparison: hero(episode: JEDI) { ...comparisonFields } } fragment comparisonFields on Character { name appearsIn friends { name } }结果{ data: { leftComparison: { name: Luke Skywalker, appearsIn: [NEWHOPE, EMPIRE, JEDI], friends: [ { name: Han Solo }, { name: Leia Organa }, { name: C-3PO }, { name: R2-D2 } ] }, rightComparison: { name: R2-D2, appearsIn: [NEWHOPE, EMPIRE, JEDI], friends: [ { name: Luke Skywalker }, { name: Han Solo }, { name: Leia Organa } ] } } }注意fragment comparisonFields on Character中的on Character片段必须绑定到一个类型或其接口/超类型服务端据此校验字段合法性。在片段内使用变量变量$前缀不仅用于操作参数也可以在片段内部引用query HeroComparison($first: Int 3) { leftComparison: hero(episode: EMPIRE) { ...comparisonFields } rightComparison: hero(episode: JEDI) { ...comparisonFields } } fragment comparisonFields on Character { name friendsConnection(first: $first) { totalCount edges { node { name } } } }结果展示了典型的“连接Connection”分页模式——totalCount给出总数edges是实际取回的页{ data: { leftComparison: { name: Luke Skywalker, friendsConnection: { totalCount: 4, edges: [ { node: { name: Han Solo } }, { node: { name: Leia Organa } } ] } }, rightComparison: { name: R2-D2, friendsConnection: { totalCount: 3, edges: [ { node: { name: Luke Skywalker } }, { node: { name: Han Solo } } ] } } } }操作名称Operation Name给操作命名后便于在服务端日志、错误信息中定位具体操作query HeroNameAndFriends { hero { name friends { name } } }结果{ data: { hero: { name: R2-D2, friends: [ { name: Luke Skywalker }, { name: Han Solo }, { name: Leia Organa } ] } } }变量Variables变量前缀必须为$后跟其类型声明声明在操作头部、使用在查询体内query HeroNameAndFriends($episode: Episode) { hero(episode: $episode) { name friends { name } } }变量把“结构”与“数据”分离同一份查询文本可以配合不同的变量值反复发送这是 GraphQL 客户端缓存查询、做持久化查询的基础。默认变量变量也可以声明默认值未提供变量时自动采用默认query HeroNameAndFriends($episode: Episode JEDI) { hero(episode: $episode) { name friends { name } } }指令Directives内置指令include/skip允许按条件包含或跳过字段配合变量即可用一份查询表达两种形态query Hero($episode: Episode, $withFriends: Boolean!) { hero(episode: $episode) { name friends include(if: $withFriends) { name } } }提供变量值{ episode: JEDI, withFriends: false }结果friends字段因条件不成立而被整体省略{ data: { hero: { name: R2-D2 } } }两条内置指令的语义include(if: Boolean)仅当参数为true时包含此字段skip(if: Boolean)当参数为true时跳过此字段。十一、变更Mutations变更用于修改数据或触发动作语法与查询类似只是操作关键字为mutation。示例为某部影片创建评论mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) { createReview(episode: $ep, review: $review) { stars commentary } }变量中$ep: Episode!与$review: ReviewInput!均为非空声明——缺省任一参数都会在执行前报错。提供的变量值{ ep: JEDI, review: { stars: 5, commentary: This is a great movie! } }结果返回创建后的评论对象{ data: { createReview: { stars: 5, commentary: This is a great movie! } } }注意review参数的类型ReviewInput!引用的是前文介绍的input对象类型——这正是“输入/输出类型分离”设计的落地场景提交评论用input返回评论用对象type。十二、内联片段与元字段Meta Fields内联片段Inline Fragments当字段返回接口或联合类型时需要用内联片段... on 具体类型来访问各实现类型特有的字段query HeroForEpisode($ep: Episode!) { hero(episode: $ep) { name ... on Droid { primaryFunction } ... on Human { height } } }变量值{ ep: JEDI }由于hero实际返回的是Droid类型只有... on Droid分支生效{ data: { hero: { name: R2-D2, primaryFunction: Astromech } } }内联片段与前文独立fragment的区别在于书写位置前者直接内嵌在字段选择集中、随操作一起定义后者独立命名、可被多处复用。元字段__typename__typename是 GraphQL 为每个类型内置的元字段返回该对象的实际类型名常用于缓存场景下区分联合类型成员{ search(text: an) { __typename ... on Human { name } ... on Droid { name } ... on Starship { name } } }结果中每条记录都带有__typename客户端可据此把Human、Starship等不同类型分开处理{ data: { search: [ { __typename: Human, name: Han Solo }, { __typename: Human, name: Leia Organa }, { __typename: Starship, name: TIE Advanced x1 } ] } }十三、这份速查表在仓库中的位置与渲染方式本清单在仓库中以 docs/graphql.md 形式存在属于 Quick Reference 速查站“编程”分区的一个条目README.md 首页导航中[GraphQL](https://link.gitcode.com/i/30637d7ee7a717a359fb41419de0f181)对应卡片其图标为 assets/graphql.svg文件名与清单文件名保持一致遵循 CONTRIBUTING.md 中“图标名称与清单名称保持一致”的约定。从源码结构看docs/目录下的每个 Markdown 文件会被构建脚本编译为独立静态页面。docs/graphql.md 中穿插的!--rehype:wrap-classrow-span-2--这类注释正是该机制的体现——按 CONTRIBUTING.md 的说明站点使用wcj/markdown-to-html转换 Markdown 并借助 rehype 属性插件支持注释语法注入样式类用于控制卡片在网格式速查页面中的跨行布局。本地可用git clone获取仓库后执行npm install与npm start启动监听、实时生成 HTML产物输出至dist目录详见 CONTRIBUTING.md 的“本地开发”一节。小结Schema 侧五大内置标量 scalar/type/interface/union/enum/input六种类型定义构成 API 的形状类型修饰符!与[]的组合精确描述每层空值承诺参数默认值与input对象让接口保持简洁且可扩展。客户端侧字段查询、别名、片段、变量、include/skip指令、内联片段与__typename元字段覆盖了“按需取数、复用结构、条件裁剪、多态处理”四大核心能力。读与写分离query只读、mutation产生副作用、subscription面向事件三者共同构成 GraphQL 的完整操作模型。对照 docs/graphql.md 中的完整示例可以随时查阅上述每一类语法的标准写法与执行结果。【免费下载链接】reference面向开发者的技术速查清单Cheat Sheets集合整理常见技术、工具与开发流程帮助快速查阅关键信息提高开发效率。项目地址: https://gitcode.com/GitHub_Trending/referen/reference创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
