Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Working With Data
  2. Graphql Operations

GraphQL Operations

Writing queries, mutations, and subscriptions with typed document nodes

Operations are how you interact with the GraphQL API. We use typed document nodes instead of auto-generated hooks, providing better flexibility and type safety.

Now that you understand the architecture and key concepts, let's learn how to write GraphQL operations. This section covers queries, mutations, and subscriptions—the core ways you interact with the GraphQL API.

Queries

Basic Query Structure

Using in Components

Before and After: Hooks vs Document Nodes

❌ Don't do this - Auto-generated Hooks

Old Pattern: Using generated hooks

Problems:

  • Less flexible than standard Apollo hooks
  • Harder to mock in tests
  • Couples you to specific codegen output
  • Often uses magic strings

✅ Do this - Typed Document Nodes

New Pattern: Using document nodes with useQuery

Benefits:

  • All Apollo Client options available
  • Easier to test with MockedProvider
  • Better IDE support and debugging
  • Type-safe variables with enums

Working with Enums

GraphQL enums are generated as TypeScript const enums, providing type safety for all enum values.

Using Generated Enums

❌ Don't do this - Magic Strings

✅ Do this - Type-Safe Enums

Enum Benefits with enumsAsConst

Our codegen configuration uses enumsAsConst: true, which generates:

This provides:

  • Tree-shakeable code (only used values are bundled)
  • Better TypeScript inference
  • Autocomplete in IDEs
  • Compile-time validation

Mutations

Basic Mutation

Using Mutations

Field Selection Best Practices

❌ Don't do this - Over-fetching

✅ Do this - Request Only What You Need

❌ Don't do this - Query Type Extractions

Problem: Extracting types from query results using TypeScript indexed access

Issues:

  • Fragile: Query structure changes break component types
  • Hard to discover: Types are hidden in query result structure
  • No reusability: Can't share these types across components
  • Poor semantics: Type path doesn't describe its purpose
  • Nullability issues: Doesn't handle nullable query results safely

Partial improvement: You can use NonNullable to handle nullability (NonNullable<Query["field"]>["subfield"]), but this still has the same limitations. See the Fragments guide for the full migration path, including the null-safe extraction pattern and the final fragment-based solution.

Variable Usage

❌ Don't do this - Unused Variables

ESLint will warn: @graphql-eslint/no-unused-variables

✅ Do this - Use All Declared Variables

Subscriptions

Basic Subscription

Using Subscriptions

Error Handling

Query Error Handling

Mutation Error Handling

Operation Naming Conventions

All operations must be named for better debugging and tooling:

Naming conventions:

  • Queries: Start with Get or describe the data (e.g., GetUser, SearchIncidents)
  • Mutations: Start with a verb (e.g., UpdateChatroom, CreateIncident)
  • Subscriptions: Start with On (e.g., OnChatroomUpdate, OnMessageReceived)

Optimistic Updates

For better UX, use optimistic updates with mutations:

Best Practices Summary

✅ Do

  • Use typed document nodes with standard Apollo hooks
  • Import and use generated enum types
  • Name all operations descriptively
  • Request only the fields you need
  • Handle errors appropriately
  • Use fragments for reusable selections

❌ Don't

  • Use auto-generated hooks from old patterns
  • Hard-code enum values as strings
  • Over-fetch data you don't use
  • Define variables you don't use
  • Use anonymous operations
  • Ignore TypeScript errors on variables

Once you're comfortable writing operations, the next section covers where to organize them using the colocation pattern.

Previous

Working with data / Pub/Sub

Next

Working with data / GraphQL Colocation

On this page

Queries
Basic Query Structure
Using in Components
Before and After: Hooks vs Document Nodes
❌ Don't do this - Auto-generated Hooks
✅ Do this - Typed Document Nodes
Working with Enums
Using Generated Enums
❌ Don't do this - Magic Strings
✅ Do this - Type-Safe Enums
Enum Benefits with enumsAsConst
Mutations
Basic Mutation
Using Mutations
Field Selection Best Practices
❌ Don't do this - Over-fetching
✅ Do this - Request Only What You Need
❌ Don't do this - Query Type Extractions
Variable Usage
❌ Don't do this - Unused Variables
✅ Do this - Use All Declared Variables
Subscriptions
Basic Subscription
Using Subscriptions
Error Handling
Query Error Handling
Mutation Error Handling
Operation Naming Conventions
Optimistic Updates
Best Practices Summary
✅ Do
❌ Don't