GraphQL tips and patterns

Practical GraphQL patterns for cleaner requests: variables, operation names, fragments, aliases, and directives.

circle-exclamation

This article covers patterns that make your GraphQL code cleaner, more maintainable, and easier to debug. If you're new to GraphQL, start with GraphQL basics first.

Variables

When you're testing queries, it's easy to write values directly into the query string. But real applications need to pass different values each time: a user might click on another device, select a different filter, or navigates to the next page.

Variables solve this by separating what you're asking for (the query) from the specific values (the variables). Think of it like a function: the query is the function definition, and variables are the arguments you pass in.

Here's a query without variables:

query GetDevice {
  device(id: "550e8400-e29b-41d4-a716-446655440001") {
    title
  }
}

And here's the same query with a variable:

query GetDevice($deviceId: ID!) {
  device(id: $deviceId) {
    title
  }
}

The variable $deviceId is declared in parentheses after the operation name. The ID! part specifies the type (must match what the schema expects). Then you use $deviceId wherever you need that value in the query.

The actual value is passed separately as JSON:

When you send the request, include both the query and the variables. GraphQL tools and client libraries handle this for you — you just provide the variables object.

Multiple variables

You can declare as many variables as you need:

In this example:

  • $orgId: ID! is required (! means it cannot be null)

  • $statusIds: [ID!] is an optional array of IDs (no ! after the brackets)

  • $limit: Int = 20 is optional with a default value of 20

Variables in JSON:

Operation names

You can give your operations custom names to make them easier to identify in logs, debugging tools, and network traces.

The name GetDevice appears after the operation type (query, mutation, or subscription). It doesn't affect execution, as the API ignores it, but helps in several ways:

  • Debugging: Error messages and server logs reference the operation name

  • Tooling: GraphQL clients use names for caching and request deduplication

  • Analytics: Track which operations are called most frequently

  • Readability: Self-documenting code, especially with multiple operations

Mutations benefit from naming too:

Common naming conventions use PascalCase with a verb prefix: GetDevice, ListDevices, UpdateAsset, CreateGeoObject, DeleteSchedule.

Fragments

Fragments let you define reusable sets of fields. They're useful when you need the same fields in multiple queries.

Define a fragment on a specific type:

Use it in queries with the spread operator (...):

Both queries now share the same field selection for core device data.

Inline fragments for interfaces

When working with interfaces like Node, use inline fragments to request type-specific fields:

The node query returns any entity by ID. The inline fragments (... on Type) tell GraphQL what fields to return based on the actual type.

Aliases

Aliases let you rename fields in the response or fetch the same field multiple times with different arguments.

Renaming fields

Response:

Comparing entities

Fetch the same entity at different points or with different parameters:

Batch mutations

Aliases enable batch operations in a single request:

Each aliased mutation executes independently. If one fails, others can still succeed (check the errors array for partial failures).

Directives

Directives modify how fields are executed. GraphQL includes six built-in directives for conditional field inclusion.

Directives can be used to:

  • Hide fields the user can't access

  • Skip expensive fields when not needed

  • Fetch fewer fields on mobile devices

See also

Last updated

Was this helpful?