Query Builder
This page explains how to graft fields together with add Query / add Child, building a GraphQL query step by step while looking at the schema.
What the Query Builder is (overview)
The Query Builder is the screen where you assemble a query by "grafting" it together one level at a time, while looking at the schema documentation in the right pane. You insert a root field with add Query, then stack add Child on each branch to expand its inside. The query you are assembling is always previewed in the Generated Query panel at the bottom, and you can copy it and send it as is.
Queries do not depend on the environment. You send an assembled query by combining it with the currently selected environment (Registering and switching environments). For terminology, see Key terms.
Prerequisites
- You have already imported a schema via Importing a schema.
- You understand the difference between leaves (scalar / enum) and branches (object / interface / union) (Browsing the schema documentation, Key terms). The Query Builder uses the same distinction.
- You understand the difference between an "environment variable" and a "GraphQL variable" (Key terms). The Query Builder itself does not resolve environment variables.
Where it is on screen
The Query Builder is on the Query tab of the center pane. The schema documentation (type catalog) is
laid out in the right pane. + query appears on the field rows in the right pane, so after you click it,
check the added root on the Query tab in the center (if the tab is on Headers / Auth, switch to the Query tab).
Split button (main button + ▼ menu)
+ query (branch field rows in the right pane) and + child (branch node rows in the builder) are each a
split button made up of two adjacent buttons.
- Main button (
+ query/+ child): commits and inserts on the spot, following its fixed default.+ querymain … always with no children (adds only the field name to the root)+ childmain … always scalars only (inserts just the leaves, one level)
- ▼ button: a two-choice menu, "Scalars only (one level)" or "All fields (one level)". Choosing one applies that granularity for that one time only (the fixed default does not change).
- Leaf fields'
+ queryhas no ▼ (since there are no children to expand, it becomes a plain button with the main button only).
Steps
1. Add a root field with add Query
- In the schema documentation in the right pane, open the Query type (or the Mutation type).
- Click the
+ querymain button at the right end of a field row on a root type (Query / Mutation. Subscription is not supported). - That field is added as a root on the Query tab in the center pane.
The + query main button never inserts children. Even a branch field is added with an empty inside
(this is by design, so you do not have to delete unwanted fields after every insertion). Since an empty
branch cannot be written as { } in GraphQL syntax, the Generated Query automatically fills it with just
__typename. After adding it, use + child in the next step to expand its inside.
If you open a branch field's ▼ and choose "Scalars only (one level)" or "All fields (one level)", you can, for that one time only, add it to the root with its immediate fields already filled in at the chosen granularity.
2. Insertion granularity (the main button's fixed default and the ▼ one-time override)
The "insertion granularity" toggle (radio buttons) that used to be in the toolbar has been removed. Granularity is now decided only by the main button's fixed default and the ▼'s one-time override.
| Action | What gets inserted |
|---|---|
+ query main |
Always no children (field name only) |
+ query ▼ |
For that one time only, "Scalars only (one level)" or "All fields (one level)" |
+ child main |
Always scalars only (leaves = scalar / enum) |
+ child ▼ |
For that one time only, "Scalars only (one level)" or "All fields (one level)" |
Options in the ▼ menu:
| Menu label | What gets inserted |
|---|---|
| Scalars only (one level) | Only the immediate leaves (scalar / enum) |
| All fields (one level) | The immediate leaves + the names of branch fields |
3. Expand one level with + child
An already inserted branch node (a field of object / interface type) shows a + child split button.
- Clicking the main button … always scalars only; inserts that type's immediate fields, one level.
- Clicking the ▼ … choosing "Scalars only (one level)" or "All fields (one level)" expands at that granularity, for that one time only.
If an expanded child is itself a branch, a + child appears on it too, so you can keep clicking to extend
deeper recursively.
Even when the main button cannot be pressed, sometimes only the ▼'s "All fields (one level)" can be. For a type that has no leaves and only branches, the main button (scalars only) is disabled because there are 0 insertable leaves, but the ▼'s "All fields (one level)" is enabled because it can insert the branch names. So the main button being unpressable does not necessarily mean you cannot add any immediate fields — always check the ▼ as well. Only when both granularities yield 0 candidates are the main button and the ▼ both disabled.
4. Add one field at a time with suggest input
Below the list of children on each branch node is an input field labeled "+ Add field (type to suggest)".
- When you type part of a field name, candidates appear by case-insensitive partial match (already-added fields are excluded). All candidates are also shown just by focusing the field.
- Use
↑↓to move through the candidates andEnterto confirm, adding just that one field as a child. After adding, the input clears so you can keep searching for the next one. Esccloses it. You can also click a candidate row with the mouse to select it.
5. Set the operation name (operationName)
In the "Operation name" field at the top of the Query tab, you can enter the name of the generated GraphQL
operation (default MyQuery). It is also reflected in the request tab name on the top bar. Characters that
are invalid as a GraphQL identifier are auto-normalized, so whatever you type, the Generated Query is always
syntactically valid GraphQL.
6. Query and Mutation cannot be mixed
The kind of the first root you add (Query or Mutation) locks add Query from then on. The opposite side's
+ query becomes disabled for both the main button and the ▼, and hovering the cursor shows this tooltip:
Already added Query fields; cannot mix Query and Mutation in one operation
To release the lock, delete all of the Query tab's root fields with × (once it is back to 0, both
Query's and Mutation's + query can be chosen again). This constraint exists because a query that mixes
Query and Mutation in the same operation is certain to be rejected by the server's validation.
7. Delete a field
Click the × button at the right end of each node row to delete that node. Deleting a branch node deletes
its descendant child nodes together with it.
8. Enter arguments
If a field has arguments, in that node's argument area choose an argument name from the schema via
"+ Add argument key", then enter a value in the type-specific value field. Once entered, it is emitted in
the Generated Query as field(name: value).
- Enter String / ID and the like without quotes (they are escaped to
"..."when the query is assembled). - Emptying a value returns it to unset (omitted), and that argument does not appear in the query (it is
not automatically turned into null or
""). - When a required argument (
Type!) is unset, a warning is shown below the preview. - Enter arrays via "+ Item", and input objects via nested key additions.
9. Switch the input mode (Inline / Variables)
At the top of the Query Builder there is an Input mode toggle [ Inline | Variables ] (kept per request). The argument values you enter are shared by both modes; the mode only switches "how the generated query is written".
- Inline (default) … writes argument values directly into the query body (as in step 8). Good for trying things on the spot.
- Variables … replaces top-level arguments with
$nameGraphQL variables, generating the formquery MyQuery($name: Type) { … }together with a variables (JSON) object of the values. Good for reusing a query or sharing it as a parameterized query.
Entering values in Variables mode is consolidated in the Variables (enter values) list (the variable matrix) that
appears at the top of the builder. Each row is $name | type | value input. An argument you have not set a value for
yet is shown as keyName (unset), and once you enter a value it becomes $name from the next render (variable names are
derived automatically from the key, and collisions are avoided automatically as id → post_id → id2). Input object and
list arguments are expanded and entered inside the value input, just as in step 8. To avoid double entry, in Variables mode
the value field on the tree side shows a reference note, "Value entered in the matrix".
Whether generated inline or with variables, the execution result is the same for standard scalar types. Switching modes does not lose the values you entered.
Note: For custom-defined scalar types, inline and variables may in rare cases be interpreted differently. Also,
{{environment variables}}written in an argument value are resolved to the selected environment's values on send (for both the query body and variables). Use the Generated Query's "Final (resolved)" toggle to check the resolved content; the original{{...}}is kept as is in history and saved data. See Sending queries and responses for send details.
10. Review and copy in the Generated Query
The Generated Query panel at the bottom of the Query tab always previews the GraphQL query generated from the tree you are assembling. The "Copy" button at the top right copies the displayed text as is to the clipboard. "Copy" is disabled when there are no roots at all.
Assembly example
Take the following fictional schema as an example.
type Query { user(id: ID!): User }
type User { id: ID! name: String posts: [Post!]! }
type Post { id: ID! title: String }
| Step | Action | Result |
|---|---|---|
| 1 | + query main on the user row |
user is added to the root (inside is empty → user { __typename }) |
| 2 | + child main on user |
The immediate leaves id name are added (the branch posts is not yet added) |
| 3 | + child ▼ "All fields (one level)" on user |
For this one time only, posts (a branch) is also added (still with no children, posts { __typename }) |
| 4 | title via Enter in the posts suggest field |
title is added as a child of posts |
The Generated Query at this point:
query MyQuery {
user {
id
name
posts {
title
}
}
}
If user has a required argument id: ID!, add id in the argument area from step 8 and enter a value
(sending it unset would cause a validation error on the server).
Tips
- It is by design that a branch looks empty right after adding and that
__typenameis filled in. When you expand that branch with+ child, it is replaced with the fields you actually added. - Tab contents you are assembling are auto-saved and restored on the next launch or when switching projects. Switching environments does not change the tab contents (because queries are environment-independent).
- Re-importing a schema does not clear the builder contents. To keep a query long-term, save it explicitly with "Add to collection", or keep a copy with "Copy".
What you cannot do at this point (limitations)
- Expanding
+ childon a field that references a union type is not supported (it is always disabled). - Subscription is not supported as a root type.
+ queryonly appears on Query / Mutation fields. - Schema-aware autocompletion in the editor is not supported.
When things go wrong
| Symptom | Likely cause | What to do |
|---|---|---|
+ query cannot be pressed (dimmed) |
The opposite kind (Query / Mutation) is already added and it is locked | Check the tooltip's reason. If you want to mix, delete all roots to release the lock |
You pressed + query but the inside is empty |
By design (the main button always adds with no children) | Expand its inside with + child on the added node |
+ child main is disabled but ▼ "All fields (one level)" can be pressed |
That type has no leaves and only branches | Open the ▼ and choose "All fields (one level)" |
Both + child main and ▼ are disabled |
All immediate fields already added, or a union type | If all are added, nothing to do. Expanding union types is not supported |
| "Copy" cannot be pressed | The Query Builder has 0 roots | Add one or more fields with + query |
An unfamiliar __typename is present |
Auto-fill for a branch with no children | Expand the branch you want with + child |
| Sending (or copying and running externally) reports "missing argument" or similar | A required argument is unset | Add the required argument and enter a value in step 8 |
Related documents
- Importing a schema: Importing a schema
- Leaves / branches, type catalog: Browsing the schema documentation
- The difference between environments and variables: Registering and switching environments / Key terms
- Sending an assembled query: Sending queries and responses
- Back to the index: User manual contents