GraphQL 格式化工具

免费在线 GraphQL 格式化工具。在浏览器中美化、压缩并校验 query、mutation 与 SDL 架构,按行列定位语法错误。零上传,零注册。

  • 在浏览器中处理
  • 数据不离开你的设备
  • 免费 · 无需注册
格式化会重新打印解析后的 GraphQL 并删除注释;压缩会删除可忽略的空白与注释。校验仅检查语法,成功时保留当前输出。Ctrl/⌘+Enter 执行格式化。
清除会清空输入、输出、状态和等待解析器的操作。焦点在工具内时,Ctrl/⌘+L 执行相同操作。
选择 2 或 4 个空格,再点击格式化应用设置。只加宽结构缩进;块字符串文字保留相对缩进。
输入查询、变更、订阅、片段或 SDL 定义,上限 10,485,760 个字符。编辑不会自动执行操作;载入示例会填入并格式化示例。
格式化和压缩会替换此只读输出。修改输入或缩进后,原输出会保留到再次格式化或压缩。
复制与下载 .graphql 使用当前完整输出。文件名为 query.graphql;编辑输入后需先格式化或压缩,才能导出更新后的内容。
示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。

实际示例

格式化前

query GetUser($id:ID!,$withPosts:Boolean!){user(id:$id){id name email posts @include(if:$withPosts){...PostSummary}}} fragment PostSummary on Post{id title publishedAt}

格式化后

query GetUser($id: ID!, $withPosts: Boolean!) {
  user(id: $id) {
    id
    name
    email
    posts @include(if: $withPosts) {
      ...PostSummary
    }
  }
}

fragment PostSummary on Post {
  id
  title
  publishedAt
}

SDL 架构

type Post {
  id: ID!
  title: String!
  publishedAt: DateTime
  author: User!
}

type Query {
  post(id: ID!): Post
  posts(authorId: ID, limit: Int = 20): [Post!]!
}

为什么要格式化 GraphQL?

一致的 GraphQL 格式直接影响 code review、schema diff 与 .graphql 文件入库。压缩后的 query 在没有 persisted query 时能减少线上传输体积;美化后的 query 在 PR 里更易扫读。把 query 单独拿出来校验,可以在发请求前发现漏掉的花括号、未闭合的字符串这类语法错误;引用了不存在的 fragment 不算语法错误,要靠结合 schema 的校验。

实现原理

本工具在浏览器中跑 graphql-js(GraphQL Foundation 维护的参考实现)。parse() 从文本构建 AST 并在首个语法错误处报出行列号;print() 把 AST 序列化为规范 GraphQL;stripIgnoredCharacters() 按 spec 移除所有 ignored token,得到压缩形式。整个过程零网络往返,数据完全留在本地。

压缩与报错示例

对上面「格式化前」的查询点击压缩,得到(graphql-js 16.14 的 stripIgnoredCharacters):

query GetUser($id:ID!$withPosts:Boolean!){user(id:$id){id name email posts@include(if:$withPosts){...PostSummary}}}fragment PostSummary on Post{id title publishedAt}

逗号在 GraphQL 里属于可忽略记号,会和空白一起删掉。query { user(id: 1) { id name } 少了一个右花括号,报错为 解析错误: Syntax Error: Expected Name, found <EOF>. (行 1, 列 32),位置指向解析器读到输入末尾的地方。

别名、变量与注释

这个查询使用不同别名请求两个用户。选择 4 个空格并点击格式化,可展开嵌套的选择集。输出保留 primary、secondary、引号中的 ID、变量默认值和 @include 指令。开头的注释会消失;其中有重要上下文时,请保留原查询。压缩保留相同操作与选择集,删除注释以及解析器允许省略的记号间空白。

输入

# Fetch two labels
query Labels($show: Boolean! = true) { primary: user(id: "a") { name } secondary: user(id: "b") @include(if: $show) { name } }

4 空格输出

query Labels($show: Boolean! = true) {
    primary: user(id: "a") {
        name
    }
    secondary: user(id: "b") @include(if: $show) {
        name
    }
}

压缩输出

query Labels($show:Boolean!=true){primary:user(id:"a"){name}secondary:user(id:"b")@include(if:$show){name}}

保留描述文字的相对缩进

描述文字可以有自己的缩进。这个 SDL 示例中,注记比前一句多缩进两个空格。使用 4 个空格格式化时,字段和描述分隔符会移到更宽的结构缩进处,注记仍比前一句多两个空格。重新解析格式化结果,得到的描述文字与输入相同,包括换行和注记前的两个空格。

输入

type Query {
  """
  Returns a label.
    Keep this note indented.
  """
  label: String
}

4 空格输出

type Query {
    """
    Returns a label.
      Keep this note indented.
    """
    label: String
}

限制

  • 格式化会删除注释。graphql-js 的 print() 按语法树重新生成文本,# 注释不在语法树里。压缩同样会删掉注释。注释需要保留时请留着原文件。
  • 校验只检查语法。{ user(id: $id) { id } } 里的 $id 没有声明,照样通过;检查变量和字段需要 schema。
  • 只报告第一个语法错误。
  • 4 空格选项只加宽由嵌套产生的缩进。""" 块字符串的起始行移到新缩进,内部文字相对它保持原有缩进:GraphQL 规范只去掉块字符串的公共缩进,加宽内部各行会改变描述文字。graphql-js 用 2 空格输出,其他工具得到的也是 2 空格。
  • 输入上限为 10,485,760 个字符。

FAQ

支持哪些 GraphQL 语法结构?

支持 query、mutation、subscription、fragment、inline fragment、variable、directive(@include / @skip / @deprecated 与自定义)以及 SDL 类型系统定义(type / interface / union / enum / input / scalar / extend / schema)。底层使用官方 `graphql` 参考实现,凡是 graphql-js 接受的都接受。

我的 schema 或查询会被上传吗?

不会。解析、打印、校验全部在你的浏览器标签页内完成,数据不会离开设备。本工具按设计就没有上传接口。

能针对远端 schema 做类型校验吗?

仅做语法级校验。本工具只检查文本是否符合 GraphQL 语法,不验证字段是否存在于某个具体 schema。需要类型感知的校验请在本地运行 `graphql-cli`、`apollo client:check` 或 `graphql-inspector` 对接你的 endpoint。

最大支持多大输入?

10 MB 硬上限。GraphQL operation 很少能写到这种体量;如果你的输入确实超过,多半是 schema introspection dump,请改用本地的 `prettier --parser graphql`。

Minify 和 Format 有什么区别?

Minify 调用 graphql-js 的 `stripIgnoredCharacters`,按 GraphQL spec 移除所有 ignored token(空白与注释),用于线上传输。Format 则把 AST 重新打印为 2 或 4 空格缩进,便于人读。