25
Backend
04
Security
08
iOS
07
Infra

Write component-specific GraphQL queries instead of reusable ones

ADR-0031 ACCEPTED · 2025-08-17
Write component-specific GraphQL queries instead of reusable ones

Decision

Give each view or component its own GraphQL operation that selects exactly the fields it shows.

query ProfileView {
  me { userId, username, email }
}

query UserMenuBadge {
  me { username }
}

Components share the schema and never share a query. Use a fragment only to keep the selection consistent across mutations that return the same type, or to match a reusable UI component. A fragment that over-fetches so unrelated components can share it repeats the mistake.

Why

A query treated like a REST endpoint, reused by every consumer and fetching every field any of them might want, throws away field selection. SQL has the same trap: nobody writes one SELECT * and reuses it everywhere. Apollo codegen generates a type per operation, so a component depends only on the fields in its own operation.

Two operations that look alike are correct. ProfileView and LoginView may both select me { userId, username, email }. Each is declaring what it shows, and a later change to one leaves the other alone.

Rejected alternatives

  • Shared queries that fetch every field any component might want. Every request over-fetches, and one component's change reaches every other component that uses the query.
  • Relay-style fragment colocation, where each child view declares a fragment and the screen's query spreads them. The child's data then arrives only through its parent's operation, so the child cannot be fetched or refetched on its own, and a change to one child's fields changes the parent's operation.

Consequences

Each request carries only what its component shows, and the operation sits next to the component. There are more operation files, and engineers used to REST read the repetition as duplication.