Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Working With Data
  2. Graphql Overview

GraphQL Overview

Introduction to GraphQL usage in the axon911-frontend monorepo

The axon911-frontend monorepo uses a unified GraphQL code generation approach to ensure type safety, maintainability, and developer productivity across all frontend applications.

Architecture Overview

Our GraphQL implementation follows these key principles:

  • Unified Code Generation: Single configuration in @prepared911/data-gql package
  • Type Safety: Full TypeScript types generated from the GraphQL schema
  • Colocation: GraphQL documents live alongside the components that use them
  • Direct Fragment Types: No runtime masking, direct property access
  • Lint Enforcement: pnpm lint:graphql (part of pnpm check) checks document layout and, with graphql-eslint, each document against the schema; oxlint rules cover how TypeScript uses Apollo

Prerequisites

Before diving into GraphQL in this monorepo, you should be familiar with:

  • TypeScript: Interfaces, types, generics, and type inference
  • React: Component patterns and hooks (especially useQuery, useMutation)
  • Apollo Client: Basic understanding of GraphQL client libraries
  • GraphQL: Query syntax, fields, variables, and basic operation types

If you're new to any of these, consider reviewing the relevant documentation first.

Documentation Structure

This GraphQL documentation is organized to follow a natural learning progression:

  1. Operations (this section): Learn to write queries, mutations, and subscriptions
  2. Colocation: Understand where to organize GraphQL files with your components
  3. Fragments: Discover type-safe patterns for reusing field selections
  4. Development: Master the day-to-day workflow, debugging, and troubleshooting

Each section builds on the previous one, so we recommend reading them in order.

Key Concepts

Schema-First Development

The GraphQL schema serves as the single source of truth for both backend and frontend. Types, enums, and interfaces are all generated from this schema, ensuring consistency across the stack.

Near-Operation-File Generation

Using the near-operation-file preset, generated types are placed in the same folder as your .graphql files:

A document file is named queries.graphql, mutations.graphql, subscriptions.graphql, or fragments.graphql, holds only that kind of definition, and lives under src/ of an app, remote, or package. pnpm lint:graphql fails otherwise, including for a file in a remote's exposes/ directory, which codegen never reads.

Typed Document Nodes

Instead of auto-generated hooks, we use typed document nodes with Apollo Client's useQuery, useMutation, and useSubscription hooks. This provides better flexibility and type safety.

Quick Start

1. Write Your GraphQL Operation

Create a queries.graphql file next to your component:

2. Run Code Generation

pnpm dev (and the shell variants) run codegen once, when they start. It does not watch: after you add or edit a .graphql file, regenerate the types yourself:

3. Use in Your Component

These rules help maintain clean, efficient GraphQL operations and prevent over-fetching.

File Organization

Next Steps

  • Operations Guide - Queries, mutations, and subscriptions
  • Colocation Patterns - Learn about organizing GraphQL files
  • Using Fragments - Type-safe data sharing
  • Development Workflow - Working with codegen

Common Patterns

Using Generated Enums

✅ Do this:

❌ Don't do this:

Type-Safe Variables

✅ Do this:

❌ Don't do this:

The TypeScript compiler catches a wrong variable type, such as limit: "20". It does not catch a magic string for an enum: with enumsAsConst, the enum type is a union of string literals, so "ACTIVE" type-checks. Use the generated const (ChatroomStatus.Active) in review; there is no lint rule for it yet.

Import Guidelines

Understanding where to import GraphQL-related types and values is crucial for maintaining proper code organization and leveraging the benefits of colocation. Our setup uses two primary import sources, each serving a specific purpose.

Import from @prepared911/data-gql

The centralized @prepared911/data-gql package contains shared, reusable types that are used across multiple components and operations:

  • Enums - Type-safe constants for GraphQL enum values

  • Input types - Types for mutation and query variables

  • Scalar types - Custom scalar types defined in the GraphQL schema

  • Shared type system types - GraphQL infrastructure types that are reused across operations

  • Factory functions (for testing) - Test data factories

These types are centralized because they represent shared concepts that don't belong to any single component or operation.

Import from Colocated .graphql Files

Component-level GraphQL files (colocated with your components) export operation-specific types and values:

  • Document nodes - Typed document nodes for use with Apollo hooks

  • Operation result types - Query, Mutation, and Subscription return types

  • Variables types - Operation-specific variable types

  • Fragment types - Component-specific fragment types

These are colocated because they represent the data contract for a specific component or operation, making it easy to see what data a component needs.

Complete Example

Here's a practical example showing both import sources used together:

Why This Matters

This import strategy provides several key benefits:

  • Colocation - Operation-specific code stays with components, making it easy to find and maintain
  • Type safety - Generated types are scoped to operations, preventing accidental misuse
  • Reusability - Enums and shared types remain centralized, avoiding duplication
  • Discoverability - Easy to see what data a component needs by looking at its colocated GraphQL files
  • Refactoring - Moving components automatically moves their GraphQL files and types

Related Documentation

  • Operations Guide - Learn how to use document nodes with Apollo hooks
  • Fragments Guide - Understand fragment types and their usage
  • Development Workflow - See how codegen generates these types

What the Lint Gate Enforces

pnpm lint:graphql runs as part of pnpm check. See "GraphQL gate" in LINT-POLICY for the full rule list. In short: documents are in the right place with the right name; every operation is named and validated against the schema (no unused variables, no deprecated fields, id selected where the type has one); and TypeScript does not use inline gql, explicit hook type arguments, or indexed access on generated result types. There is no suppressions file: fix the document.

Previous

Working with data / Remote Data

Next

Working with data / Pub/Sub

On this page

Architecture Overview
Prerequisites
Documentation Structure
Key Concepts
Schema-First Development
Near-Operation-File Generation
Typed Document Nodes
Quick Start
1. Write Your GraphQL Operation
2. Run Code Generation
3. Use in Your Component
File Organization
Next Steps
Common Patterns
Using Generated Enums
Type-Safe Variables
Import Guidelines
Import from @prepared911/data-gql
Import from Colocated .graphql Files
Complete Example
Why This Matters
Related Documentation
What the Lint Gate Enforces