Skip to content

/web-data-fetching-graphql-apollo

Apollo Client GraphQL patterns - useQuery, useMutation, cache management, optimistic updates, subscriptions

shell
$ npx -y skills add agents-inc/skills --skill web-data-fetching-graphql-apollo --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/web-data-fetching-graphql-apollo
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

Apollo Client GraphQL patterns - useQuery, useMutation, cache management, optimistic updates, subscriptions

SKILL.md

web-data-fetching-graphql-apollo.SKILL.md
name: web-data-fetching-graphql-apollo
description: Apollo Client GraphQL patterns - useQuery, useMutation, cache management, optimistic updates, subscriptions

Apollo Client GraphQL Patterns

> **Quick Guide:** Use Apollo Client for GraphQL APIs. Provides automatic normalized caching, optimistic updates, and real-time subscriptions. Always use GraphQL Codegen for type safety. Configure `keyFields` on every entity type for proper cache normalization. Use `errorPolicy: "all"` for graceful degradation. **v3.9+** adds Suspense hooks; **v4.0** moves React imports to `@apollo/client/react` and adds `dataState` for type-safe query state.

---

<critical_requirements>

CRITICAL: Before Using This Skill

**(You MUST use GraphQL Codegen for type generation - NEVER write manual TypeScript types for GraphQL)**

**(You MUST include `__typename` and `id` in all optimistic responses for cache normalization)**

**(You MUST configure type policies with appropriate `keyFields` for every entity type)**

**(You MUST use named constants for ALL timeout, retry, and polling values - NO magic numbers)**

</critical_requirements>

---

**Auto-detection:** Apollo Client, useQuery, useMutation, useSubscription, useSuspenseQuery, useLoadableQuery, useBackgroundQuery, useFragment, ApolloClient, InMemoryCache, gql, GraphQL, optimistic updates, cache policies, createQueryPreloader

**When to use:**

  • Fetching data from GraphQL APIs
  • Real-time updates with GraphQL subscriptions
  • Complex cache management with normalized data
  • Optimistic UI updates for mutations
  • Applications already using a GraphQL server

**When NOT to use:**

  • REST APIs (use your data fetching solution instead)
  • Simple APIs without caching needs (consider fetch directly)
  • When GraphQL Codegen cannot be integrated

**Key patterns covered:**

  • Client setup with InMemoryCache and type policies
  • useQuery / useLazyQuery for queries with loading, error, and data states
  • useMutation with optimistic updates, cache.modify, and cache.evict
  • useSubscription for real-time WebSocket data
  • Pagination with fetchMore and relayStylePagination
  • Fragment colocation and useFragment
  • Reactive variables for local client state
  • Suspense hooks: useSuspenseQuery, useLoadableQuery, useBackgroundQuery, createQueryPreloader

**Detailed Resources:**

  • [examples/core.md](examples/core.md) - Client setup, useQuery, useMutation with cache updates
  • [examples/pagination.md](examples/pagination.md) - Infinite scroll, relay pagination type policies
  • [examples/fragments.md](examples/fragments.md) - Fragment definitions, composition, colocation
  • [examples/error-handling.md](examples/error-handling.md) - Component-level and global error handling
  • [examples/subscriptions.md](examples/subscriptions.md) - WebSocket link setup, useSubscription with cache updates
  • [examples/testing.md](examples/testing.md) - MockedProvider, component tests, schema-based testing
  • [examples/suspense.md](examples/suspense.md) - v3.9+ Suspense hooks (useSuspenseQuery, useLoadableQuery, useBackgroundQuery)
  • [reference.md](reference.md) - Decision frameworks, API reference tables, anti-patterns

---

<philosophy>

Philosophy

Apollo Client is a comprehensive GraphQL client that provides intelligent normalized caching, reducing redundant network requests and keeping your UI consistent across components.

**Core Principles:**

1. **Normalized Cache**: Data is stored once by type and ID, referenced everywhere - update in one place, UI reflects everywhere 2. **Declarative Data Fetching**: Components declare what data they need via GraphQL, Apollo handles caching, deduplication, and network 3. **Optimistic UI**: Show expected results immediately, rollback automatically on server error 4. **Type Safety**: GraphQL Codegen generates TypeScript types from your schema - never write response types manually

**Data Flow:**

1. Component requests data via useQuery/useMutation 2. Apollo checks InMemoryCache (normalized by `__typename` + `keyFields`) 3. If cache miss or stale, fetches from network 4. Response is normalized and stored in cache 5. All components watching that data re-render automatically

</philosophy>

---

<patterns>

Core Patterns

Pattern 1: Client Setup and Configuration

Configure ApolloClient with InMemoryCache, type policies for cache normalization, and link chain for error handling and auth. Environment variables should use your framework's convention for the GraphQL endpoint.

const cache = new InMemoryCache({
  typePolicies: {
    User: { keyFields: ["id"] },
    Product: { keyFields: ["sku"] }, // Non-default identifier
    CartItem: { keyFields: false }, // Embed in parent, don't normalize
    Query: {
      fields: {
        usersConnection: relayStylePagination(["filter"]),
      },
    },
  },
});

**Key decisions:** `keyFields` determines how entities are identified in cache. Use `["id"]` (default), custom field like `["sku"]`, composite `["authorId", "postId"]`, or `false` for embedded types.

See [examples/core.md](examples/core.md) Pattern 1 for complete client setup with auth link, error link, and codegen configuration.

---

Pattern 2: useQuery for Data Fetching

Declare data requirements with `useQuery`. Always handle loading, error, and empty states. Use `cache-and-network` for stale-while-revalidate behavior.

const { data, loading, error, refetch } = useQuery<GetUsersQuery, GetUsersQueryVariables>(
  GET_USERS,
  {
    variables: { limit: DEFAULT_PAGE_SIZE },
    fetchPolicy: "cache-and-network",
    skip: !shouldFetch,
  }
);

if (loading && !data) return <Skeleton />;
if (error) return <Error message={error.message} onRetry={() => refetch()} />;
if (!data?.users?.length) return <EmptyState />;

**Why this pattern:** `loading && !data` shows skeleton only on initial load (not background refetch). `cache-and-network` shows cached data immediately while refreshing from network.

See [examples/core.md](exam

Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin, auto-invoked