GraphQL Formatter & Validator
Format, validate and convert GraphQL: queries, schemas, introspection JSON and TypeScript.
Queries, mutations, subscriptions, fragments or schema SDL. Checked as you type; Ctrl/⌘ + Enter formats.
Schema to validate against optional · SDL or introspection JSON
The operations in the document are checked against it. Get the JSON of a live API with the introspection query on the Introspection ⇄ SDL tab.
Problems
JSON is turned into SDL, SDL into the introspection JSON a server with that schema would return.
Problems in the schema
Each named operation gets a result type and a variables type; each fragment a …Fragment type.
Problems
An object, a list of objects, or a whole GraphQL response. Items of a list are merged into one type.
About the GraphQL Formatter & Validator
Paste a GraphQL query, mutation, subscription, fragment file or schema (SDL). As you type, the tool parses it and lists every problem with its line and column — a missing brace, an unknown field ("Cannot query field "bio" on type "Author""), an argument of the wrong type, an unused variable — with a Show button that selects the spot in the editor. Format lays the document out with Prettier's GraphQL printer and keeps your comments; Minify removes everything that does not change the meaning, for GET requests and persisted queries.
Add your schema — as SDL, or as the JSON a server returns to the introspection query — and the operations are checked against it with every validation rule of the GraphQL specification (the edition that added @oneOf input objects): fields and their arguments, types of values and variables, fragments, directives and field merging. The other tabs convert an introspection result to SDL and back, write TypeScript types for the schema and for the exact shape of each operation's result, and draft a schema from a sample JSON response. Everything runs in your browser.
How to use it
- Paste a document into GraphQL document (or open a
.graphql/.gqlfile, or pick a sample). Problems appear on the right as you type; Show jumps to each one. - To check fields and types, open Schema to validate against and paste the schema: SDL, or an introspection result (
{"data": {"__schema": …}}). Large schemas are fine. - Press Format (Ctrl/⌘ + Enter) or Minify, then copy or download the result. Indentation, line width and spaces inside braces can be changed.
- Use Introspection ⇄ SDL to turn a server's introspection JSON into readable SDL (or the other way), TypeScript to generate types from the schema and your operations, and JSON → SDL to start a schema from a sample response.
Examples
Schema: type Author { name: String! books: [Book!]! }
Query: { book(id: 1) { author { nmae } } }Line 1, column 26 · Cannot query field "nmae" on type "Author". Did you mean "name"?
mutation AddReview($input: ReviewInput) {
addReview(input: $input) { rating }
} # addReview(input: ReviewInput!)Line 2, column 20 · Variable "$input" of type "ReviewInput" used in position expecting type "ReviewInput!".
Declare the variable as ReviewInput!, or give it a default value.
query BookPage($id: ID!) {
book(id: $id) {
title # shown on the page
author { name }
}
}query BookPage($id:ID!){book(id:$id){title author{name}}}query Search($text: String!) {
search(text: $text) { __typename ... on Book { title } ... on Author { name } }
}export type SearchQuery = {
search: Array<({
__typename: 'Book';
title: string;
}) | ({
__typename: 'Author';
name: string;
})>;
};Common uses
- Tidying a query copied from logs, network tabs or a minified client bundle before reading or committing it.
- Finding why a server rejects a query — the same rule is reported here, with its exact place, before you send it.
- Reviewing a schema change: duplicate fields, broken interface implementations, union members that are not objects, input cycles.
- Turning the introspection JSON of an API you use into SDL you can read and diff, or producing introspection JSON for tools that need it.
- Typing API calls in a TypeScript front end without setting up a code generator.
What the validator checks
Syntax, with the reference implementation's wording ("Syntax Error: Expected Name, found "}".") and an exact position — including descriptions on operations and variables (allowed since the edition of the specification that added @oneOf).
Operations against a schema: every rule of section 5 of the specification — operation names and types (a mutation needs a Mutation type), fields that exist (with "did you mean"), sub-selections on objects and none on scalars, field merging (two fields with one response name must ask for the same thing), argument names and required arguments, value types (32-bit Int, enums, input objects, @oneOf), fragments (defined, used, on composite types, spreadable here, no cycles), directives (defined, allowed in that place, not repeated), and variables (unique, input types, defined, used, and allowed where they are used). Subscriptions must select one root field, without @skip or @include at the top.
Without a schema the rules that need none still run: names, fragments, variables, duplicate arguments and @skip / @include.
Schemas: unknown types (with suggestions), duplicate types, fields, arguments and enum values, extensions of missing types, root types, interface implementation (missing fields, incompatible types, missing or extra required arguments, transitive interfaces), union members, empty types, input/output positions, input objects that require themselves, @oneOf rules, deprecation rules, directives used where they are not allowed, and default values that do not fit their type.
Introspection ⇄ SDL
Servers describe their schema in JSON when they receive the introspection query; Copy introspection query gives you that query to run in your GraphQL client. Paste the whole response ({"data": {"__schema": …}}) to get SDL, or paste SDL to get the JSON that a server with that schema would return — with the built-in scalars it uses, the introspection types and the standard directives, like graphql-js introspectionFromSchema. The SDL output leaves out built-in definitions, prints a schema { … } block only when the root types are not called Query, Mutation and Subscription, and keeps descriptions, deprecations, @specifiedBy and @oneOf.
The newer fields option of the query also asks for the schema description, specifiedByURL, isRepeatable, deprecated arguments and input fields, and isOneOf. Servers built before those were specified answer it with an error; use the standard query for them.
TypeScript output
For the schema: enums (string unions, enum or a const object), object and interface types (interface User extends Node), unions, input types (nullable or defaulted fields optional) and QueryUserArgs-style argument types. Nullable output fields are field?: T | null by default. Custom scalars are unknown until you map them (DateTime=string, Upload=File), or use a Scalars map.
For each named operation, a …Variables type and the exact result: only the fields you selected, aliases as keys, __typename as a literal type, fields under @include / @skip optional, and one member per possible type for unions and interfaces (types that would get the same shape are merged). Fragments get …Fragment types.
Limitations
- This is an independent implementation of the specification written for this page, not graphql-js. Messages follow graphql-js where it has one, so they look familiar, but wording can differ, and graphql-js versions differ among themselves.
- Server-specific rules are unknown here: query depth or cost limits, persisted-query lists, and the meaning of custom directives. Federation directives such as
@keycount as unknown unless the schema defines them — paste the subgraph SDL with itsdirectivedefinitions. - Values of custom scalars are accepted as written, because their format is up to the server.
- Experimental syntax that is not in the specification (fragment arguments, client-controlled nullability) is reported as a syntax error.
- Formatting needs a document that parses. The TypeScript output is a starting point for hand-written code, not a replacement for a code generator's plugins (no resolver types).
- Inferring SDL from JSON can only see the sample: nullability, enums and IDs are guesses to review.
Privacy
Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.
Frequently asked questions
Is my query or schema uploaded?
No. Parsing, validation, formatting and conversion all run in your browser, and the page works offline once it has loaded. Nothing is sent to a GraphQL server either: to get an introspection result you run the query yourself and paste the response.
How do I get the introspection JSON of my API?
Press Copy introspection query on the Introspection ⇄ SDL tab and run that query against the API with any GraphQL client (Altair, Insomnia, Postman, GraphiQL) or with curl as a POST of {"query": "…"}. Paste the whole response. If the server has introspection switched off (common in production), ask for the SDL instead or use a staging server.
Does Format change what my query does?
No. It only changes layout: indentation, line breaks, commas and spaces. Comments are kept. Minify also removes comments and all optional whitespace and commas; the result means the same and reads back to the same document.
Why is a fragment "never used"?
The specification makes every fragment in a document reachable from an operation in it. A document of fragments only (a shared fragments file) is not reported this way here; spread the fragment in an operation or move it to the file where it is used.
Can I validate without a schema?
Yes: syntax and the rules that need no schema (operation and fragment names, unknown or unused fragments and variables, duplicate arguments, @skip and @include) are checked. Field names, argument types and values need the schema.
Which GraphQL version is supported?
The edition of the GraphQL specification that added @oneOf input objects, descriptions on operations and variables, deprecated arguments and input fields, and the rule that operation types must exist in the schema. Documents written for older editions are valid in it too.