GalleonQL Manual
Changelog

Query Builder

This page explains how to build up fields with add Query / add Child, assembling 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 one level at a time, while looking at the schema documentation in the left panel. 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 PREVIEW panel at the bottom, and you can copy it and send it as is.

A query doesn't depend on the environment — when you send it, it's combined with whichever environment is currently selected (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 request pane. The schema documentation (type catalog) is laid out in the left panel when you press "Schema" on the rail at the far left (the schema panel; the app starts with it showing). + query appears on the field rows in the schema panel, so after you click it, check the added root on the Query tab of the request pane (if the tab is on Headers / Auth, switch to the Query tab). Building a query does not close the schema panel automatically.

Split button (main button + ▼ menu)

+ query (branch field rows in the schema panel) 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.
    • + query main button … always adds with no children (field name only)
    • + child main button … always adds scalars only (just the leaves, one level deep)
  • ▼ 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).
  • A leaf field's + query has no ▼ — with no children to expand, it's just a plain button.

Telling input (arguments) from response (fields to fetch)

The builder tree mixes two things: the values you send to the server and the shape you receive back. Which range you are looking at is shown by a heading and the style of the vertical rule.

Range Heading Vertical rule Meaning
Input Input / Arguments solid Where you enter values (the arguments)
Response Response / Fields to fetch dashed Where you choose which fields to receive

Because the distinction is carried by the heading text and the rule style, it still reads when colors are hard to tell apart. Input / Arguments appears for every field that has arguments. Response / Fields to fetch appears only at the root (the levels below it are a continuation of the response).

Steps

1. Add a root field with add Query

  1. In the schema documentation in the schema panel, open the Query type (or the Mutation / Subscription type).
  2. On a root type (Query / Mutation / Subscription), click the + query main button at the left edge of the field row.
  3. A new request tab opens with that field as its root, and the app switches to it.
The schema panel, showing the user field row on the Query type with the insert button at the start of the row
① The + at the start of the row opens a new tab with that field as its root

Pressing the same query twice does not add another tab. If one is already open, it moves to that tab instead of creating a new one, and the tab at the top flashes briefly to show you where it is.

Hold Ctrl and click + to open it in a new tab regardless (useful for trying the same query with different arguments side by side). This is a mouse click with Ctrl held, not the + key on the keyboard.

If the schema has no Subscription type, the + query buttons for Subscription are not shown at all rather than shown disabled.

The + query main button never inserts children. Even a branch field is added empty on the inside — this is intentional, so you don't have to delete unwanted fields after every insertion. Because GraphQL syntax doesn't allow an empty branch to be written as { }, the PREVIEW automatically fills it in with just __typename. Once it's added, use + child in the next step to expand what's inside.

The query builder right after inserting, with user at the root and nothing inside it yet
① The root that was just added. Because it is empty, the PREVIEW fills it with __typename alone

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 adds with no children (field name only)
+ query ▼ For that one time only, "Scalars only (one level)" or "All fields (one level)"
+ child main Always adds 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) Just the immediate leaves (scalar / enum)
All fields (one level) The immediate leaves, plus 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 inserts only scalars, adding that type's immediate fields one level deep.
  • Clicking the ▼ … choosing "Scalars only (one level)" or "All fields (one level)" expands at that granularity, for that one time only.
The + child split button with its granularity menu open
① the main button (always scalars only) ② the ▼ ③ the menu, which applies 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)".

  1. 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.
  2. Use ↑ ↓ to move through the candidates and Enter to confirm, adding just that one field as a child. After adding, the input clears so you can keep searching for the next one.
  3. Esc closes it. You can also click a candidate row with the mouse to select it.
The suggest field with po typed in and posts offered as a candidate
① typing narrows the candidates ② a candidate; Enter adds just that one field as a child

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 query in the PREVIEW is always syntactically valid GraphQL.

GetUser entered in the operation name field, with the request tab now named GetUser as well
① the operation name field ② the request tab, which takes the same name

6. Query, Mutation, and Subscription cannot be mixed

A single tab can hold roots of one kind only (an operation that mixes kinds is certain to be rejected by the server's validation). That is why + always opens the query in a new tab — when you want to try another kind, there is nothing to release: just press +.

6-2. A subscription can have only one root field

The GraphQL specification allows a subscription to have exactly one root field. This too is kept naturally by + opening a new tab (one tab = one subscription).

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.

A child field row, with the delete button at its right end
① a field row ② the × at its right end; it removes the row (and, for a branch, everything under 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 PREVIEW 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.
  • When the pane is too narrow for an argument name and its value field on one line, the value field moves to the line below the name (the field is never squeezed and its text is never cut off).
The id argument added to user, with u1 entered as its value
① the argument key you added and its type (ID! means required) ② the value field for that type

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 toggle appears only after you have added at least one argument key to the query. 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 $name GraphQL variables, generating the form query MyQuery($name: Type) { … } together with a variables (JSON) object of the values. Good for reusing a query or sharing it as a parameterized query.

In Variables mode, you enter values in the Variables (enter values) list (the variable matrix) that appears below the tree you're building. Each row shows $name | type | value input. An argument with no value yet is shown as keyName (unset); once you enter a value, it's shown as $name from then on (variable names are derived automatically from the key, with collisions resolved automatically — for example id → post_id → id2). Input object and list arguments are expanded and entered inside the value field, the same as in step 8. To avoid entering a value twice, in Variables mode the value field on the tree side just shows a reference note: "Value entered in the matrix".

The variable list below the tree when the input mode is Variables
① the variable name (it becomes $name once a value is entered) ② the value field

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 PREVIEW'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 PREVIEW

The PREVIEW 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.

The PREVIEW panel with the Copy button at its top right
① copies the text as displayed to the clipboard

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 Click + query main on the user row user is added as the root, with nothing inside yet (→ user { __typename })
2 Click + child main on user The immediate leaves id and name are added (the branch posts isn't added yet)
3 Choose + 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 Type title and press Enter in the posts suggestion field title is added as a child of posts

The PREVIEW 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 __typename is 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 + child on a field that references a union type is not supported (it is always disabled).
  • Schema-aware autocompletion in the editor is not supported.

When things go wrong

Symptom Likely cause What to do
Pressing + added a new tab By design (+ opens the query in a tab) Pressing the same query twice does not add another (it moves to the existing tab and flashes it)
You pressed + query but the inside is empty By design (the main button always adds with no children) Expand it with + child on the added node
+ child main is disabled but ▼ "All fields (one level)" can be pressed The type has only branches, no leaves Open the ▼ and choose "All fields (one level)"
Both + child main and ▼ are disabled All immediate fields are already added, or this is a union-type field (not supported) If everything's already added, there's nothing to do — expanding union types isn't supported
"Copy" cannot be pressed The query builder has no root fields yet Add one or more fields with + query
An unfamiliar __typename is present This is the auto-fill for a branch that has no children yet Expand the branch you want with + child
Sending (or copying and running externally) reports "missing argument" or similar A required argument hasn't been set Add the required argument and enter a value in step 8

Related documents