How to Generate GraphQL Types From JSON
Paste representative JSON to infer GraphQL type definitions. The output is a schema prototype, not a running API. Add query roots, resolvers and authorization in your server implementation.
Mapping JSON Values to GraphQL Scalars
JSON strings and booleans map to GraphQL scalar types. Numbers require a decision between Int, Float and custom scalars. GraphQL Int is limited to signed 32-bit values, unlike every possible JSON number.
Nested Objects and Lists
Nested objects become named types and arrays become list fields. Review lists containing mixed types or empty values, since examples alone cannot describe every permitted element.
Nullable Fields and Schema Decisions
An observed non-null value does not prove a field is always present. Choose non-null markers from API guarantees rather than a lucky sample. Null values require an intentional scalar or object-type decision.
From Sample Data to Production Schema
Review naming, scalar ranges, repeated structures and business meaning. Add descriptions and tests for the actual API. Generated definitions are a starting point for a contract, not proof that a response conforms to it.
More examples and technical details
Schema Definition Language Basics
GraphQL schemas are written in SDL, a small declarative language with very few concepts. A type declares a named object with a set of fields. Each field has a name and a type. The leaf types are scalars, which hold actual values rather than further structure.
Generating SDL from a JSON sample maps cleanly: each object becomes a type, each key becomes a field, each nested object becomes another type, and each array becomes a list. The generator's job is choosing scalars and inventing type names.
Side by Side Example
A blog post payload and the schema it produces.
JSON input
GraphQL SDL
Scalar Mapping
| JSON value | GraphQL scalar | Notes |
|---|---|---|
| Text | String | UTF-8, the default for anything textual |
| Whole number | Int | Signed 32 bit, range roughly plus or minus 2.1 billion |
| Decimal number | Float | Double precision, do not use for currency |
| true or false | Boolean | Direct mapping |
| A key named id or ending in _id | ID | Serialised as a string, signals an identifier |
| Large integer such as a millisecond timestamp | Float or a custom scalar | Exceeds Int range, a BigInt scalar is cleaner |
| ISO date string | String or a custom DateTime scalar | GraphQL has no built-in date type |
| Null only | String, best guess | Nothing to infer from |
| Object | A new type | Named from the key, PascalCased |
| Array | A list type | Element type inferred from the first element |
Int overflowing is a real production issue rather than a theoretical one. A Unix timestamp in milliseconds is about 1.7 trillion, comfortably outside the 32 bit range, and a server will raise a serialisation error when it tries to return it as an Int. Define a custom scalar for large numbers, dates, and money.
Nullability Is Inverted
This is the concept that trips up everyone arriving from another language. In GraphQL, every field is nullable by default. The exclamation mark marks a field as non-null. It is the opposite of TypeScript, where a field is required unless you mark it optional.
The reason is error handling. If a resolver fails, GraphQL returns null for that field and reports the error alongside the partial data. Marking a field non-null removes that option: the error must propagate upward to the nearest nullable parent, and if there is none, the entire response data becomes null. Non-null is therefore a statement about failure behaviour, not just about data.
Lists have four combinations
| Written as | The list itself | Each item | Reads as |
|---|---|---|---|
| [Comment] | May be null | May be null | Loosest, allows null holes in the list |
| [Comment!] | May be null | Never null | Either no list, or a clean list |
| [Comment]! | Never null | May be null | Always a list, possibly with null entries |
| [Comment!]! | Never null | Never null | Always a list, always clean, usually what you want |
For a collection, [Comment!]! is nearly always the right choice, because an empty list already expresses the absence of results and a null list adds a second empty case for clients to handle.
Naming Conventions
- Types are PascalCase and singular: Post, Comment, AuthorProfile.
- Fields are camelCase, so a JSON key of word_count becomes wordCount.
- Enum types are PascalCase and their values are SCREAMING_SNAKE_CASE.
- Input types used as mutation arguments are suffixed with Input, as in CreatePostInput.
- Boolean fields read naturally as questions: isPublished or hasComments rather than published_flag.
- Avoid the Get prefix on query fields. The field is post, not getPost, because the operation type already says it is a read.
A Generated Schema Is a Starting Point
What comes out of a JSON sample is a set of object types. A working GraphQL API needs considerably more, and none of it can be inferred from data.
- A Query type defining the entry points, including arguments for filtering and pagination.
- A Mutation type for writes, with input types rather than long argument lists.
- Resolvers, since the schema describes shape and nothing about where data comes from.
- Deliberate nullability. The generator marks fields non-null because the sample had values, which is not the same as those fields being guaranteed.
- Enums for fields with a fixed set of values. A status field typed String tells a client nothing, while an enum makes the possibilities discoverable in any GraphQL explorer.
- Interfaces and unions where several types share a shape or a field can return one of several types.
- Pagination, usually the connection pattern with edges, nodes, and a cursor, rather than a bare list.
- Descriptions, written in triple quoted strings. They surface as documentation in every GraphQL client and cost almost nothing to add.
Two more things the generator cannot see: a field that appeared once in your sample may be repeatable in reality and should be a list, and circular references between types are normal in GraphQL but impossible to spot in a single flat payload.
Schema definitions pair naturally with other type artefacts. Visit the full converter collection for JSON to TypeScript to type the client side of the same payload, JSON Schema for runtime request validation, and JSON to SQL for the tables your resolvers will read from.
Frequently asked questions
Can JSON be converted directly into a GraphQL schema?
It can infer type definitions from examples, but a complete API still needs roots, resolvers and application rules.
How are arrays represented?
Arrays map to GraphQL list fields; review the inferred element type.
How are null values treated?
Null cannot identify a useful scalar by itself. Choose the intended nullable type manually.
Should generated types be reviewed before production use?
Yes. Review names, scalar ranges, nullability and actual API guarantees.
Is JSON uploaded?
No. Input is processed in this browser tab and is not uploaded by the tool. Copy and download are actions you control; ordinary page analytics do not receive tool input.