PureDevTools

GraphQL Query Builder

Visually construct GraphQL queries — variables, nested fields, aliases, fragments, and directives

All processing happens in your browser. No data is sent to any server.

Operation

Variables

Declare $name: Type inputs passed at execution time. Check ! for required.

Fields

Type field names. Click args for arguments, @dir for directives, {} for nested sub-fields.

Fragments

Named fragments are spread automatically inside the operation body as ...FragmentName

You need a GraphQL query that fetches a user’s posts with comments, uses variables for the user ID, aliases two different posts calls (recent and popular), and includes a fragment for the shared author fields. Writing it by hand means matching braces across 4 nesting levels, remembering the $variable: Type! syntax, and hoping you didn’t forget a closing brace. One typo and the GraphQL playground gives you a cryptic syntax error.

Why This Builder (Not GraphiQL or Apollo Sandbox)

GraphiQL and Apollo Sandbox require a running GraphQL server with introspection enabled — great for existing APIs, useless when you’re drafting queries for a schema that’s still being designed, or writing documentation examples. This tool builds queries visually — add fields, nest objects, define variables, create fragments, set aliases, add directives — and outputs the complete GraphQL document. Everything runs in your browser; no server connection needed, no data sent anywhere.

What Is a GraphQL Query?

GraphQL is a query language for APIs that gives clients precise control over the data they receive. Unlike REST endpoints that return fixed response shapes, a GraphQL query is a selection set — you specify exactly which fields you want, at any nesting depth, and the server returns only that data.

A GraphQL document can contain three operation types:

Anatomy of a GraphQL Query

query GetUser($userId: ID!, $showEmail: Boolean = true) {
  user(id: $userId) {
    id
    name
    email @include(if: $showEmail)
    posts {
      title
      publishedAt
    }
  }
  ...UserMeta
}

fragment UserMeta on User {
  createdAt
  role
}

This example demonstrates all the core building blocks:

ElementExamplePurpose
Operation typequeryDeclares intent (read)
Operation nameGetUserIdentifies this operation for logging/caching
Variable definition$userId: ID!Declares a required input variable
Field selectionid, nameChooses which fields to return
Field argumentuser(id: $userId)Passes a value into a field resolver
Directive@include(if: $showEmail)Conditionally includes a field
Nested selectionposts { title }Traverses object relationships
Fragment spread...UserMetaReuses a named set of fields

Variables: Keeping Queries Reusable

Hard-coding values directly in a query makes it impossible to reuse. GraphQL variables solve this:

# Bad: hard-coded
query { user(id: "123") { name } }

# Good: parameterized
query GetUser($userId: ID!) {
  user(id: $userId) { name }
}

Variables are declared in the operation signature with a $ prefix and their type. The ! suffix marks a variable as required. Variables without ! are optional and may have a default value.

Common GraphQL scalar types for variables:

TypeDescription
StringUTF-8 text
Int32-bit integer
FloatDouble-precision float
Booleantrue or false
IDUnique identifier (serialized as String)

Custom scalar types (like DateTime, JSON, Upload) depend on the schema.

Fragments: Reusable Field Sets

Fragments let you define a named selection set once and spread it across multiple queries:

fragment UserCard on User {
  id
  name
  avatarUrl
  email
}

query GetUser($id: ID!) {
  user(id: $id) {
    ...UserCard
    posts { title }
  }
}

query GetTeam($teamId: ID!) {
  team(id: $teamId) {
    members {
      ...UserCard
    }
  }
}

Fragments are especially useful in component-driven UIs (React, Vue) where each component declares its own data requirements as a fragment, and parent components compose them.

Aliases: Requesting the Same Field Twice

Aliases rename a field in the response. This is useful when you need the same field with different arguments in one query:

query ComparePrices {
  usdPrice: product(currency: "USD") { price }
  eurPrice: product(currency: "EUR") { price }
}

Without aliases, both selections would collide on product in the response.

Directives: Conditional Fields

GraphQL has two built-in directives for conditional field inclusion:

query GetProfile($showPrivate: Boolean!) {
  user {
    name
    email @include(if: $showPrivate)
    phone @skip(if: $showPrivate)
  }
}

This avoids writing separate queries for different views of the same data.

Nested Fields and Object Relationships

GraphQL traverses object relationships through nested selection sets. Each nested { } block selects fields from the type returned by the parent field:

query {
  organization {          # returns Organization
    name
    teams {               # returns [Team]
      name
      members {           # returns [User]
        id
        name
        role
      }
    }
  }
}

The depth of nesting is unlimited in the query syntax, though servers typically enforce a maximum depth limit (often 10–15 levels) to prevent denial-of-service attacks.

Field Arguments

Arguments customize what a field resolver returns. Any field can accept arguments:

query {
  users(limit: 10, offset: 20, orderBy: CREATED_AT_DESC) {
    id
    name
  }
}

Argument values can be:

Mutations: Writing Data

Mutations follow the same syntax as queries but use the mutation keyword:

mutation CreatePost($input: CreatePostInput!) {
  createPost(input: $input) {
    id
    title
    slug
    author {
      name
    }
  }
}

The selection set on a mutation specifies what the server should return after the write operation — this allows the client to update its cache in one round-trip.

Subscriptions: Real-Time Data

Subscriptions maintain a persistent connection (typically WebSocket) and push updates:

subscription OnMessageAdded($channelId: ID!) {
  messageAdded(channelId: $channelId) {
    id
    text
    sender {
      name
      avatarUrl
    }
  }
}

GraphQL vs REST: When to Use Each

CriterionGraphQLREST
Data shapeClient-definedServer-defined
Over-fetchingEliminatedCommon
Under-fetchingEliminated (one query)Often requires multiple requests
CachingComplex (requires @cache hints or persisted queries)Simple (HTTP caching)
File uploadsRequires multipart specNative support
SchemaStrongly typedOptional (OpenAPI)
ToolingApollo, urql, URQLFetch, Axios, SWR

GraphQL excels in: complex data graphs, mobile apps (bandwidth-sensitive), component-driven UIs, and API aggregation. REST excels in: simple CRUD resources, file transfers, and scenarios where HTTP caching is critical.

How to Use This Tool

  1. Select operation type — choose query, mutation, or subscription
  2. Name the operation — optional but recommended for debugging and Apollo DevTools
  3. Add variables — declare $name: Type pairs; check “Required” for mandatory inputs
  4. Add fields — type field names; click args to add arguments, @dir for directives, {} to nest sub-fields
  5. Add fragments — name, type condition (on TypeName), and fields; the tool spreads them automatically
  6. Copy the generated query and variables JSON into your GraphQL client (Apollo Studio, GraphiQL, Insomnia, etc.)

Related Tools

More Data Converter Tools