GraphQL has three fundamental operations: Query for reading data, Mutation for writing/modifying data, and Subscription for real-time data streaming.
GraphQL defines three primary operation types that map to different ways of interacting with data. These operations are the entry points into any GraphQL schema and determine how clients can request or modify data. Each operation has distinct characteristics and use cases, with queries for fetching, mutations for changing state, and subscriptions for real-time updates.
Purpose: Fetch data without side effects. Equivalent to GET in REST.
Characteristics: Can be executed multiple times with same result; support for caching; can be sent via GET or POST.
Key Features: Field selection (choose exactly what you need), aliases (rename fields), fragments (reusable field sets), arguments (filtering, pagination).
Execution: Runs in parallel; resolvers for fields can be batched.
Example: query GetUser { user(id: "123") { name email posts { title } } }
Purpose: Create, update, or delete data with side effects. Equivalent to POST, PUT, PATCH, DELETE in REST.
Characteristics: Executed serially (one after another) to ensure data consistency; can return the modified data.
Key Features: Input types for structured arguments; can update multiple resources; can read back updated state.
Best Practice: Always return the mutated object so clients can update their cache without additional queries.
Example: mutation CreateUser($input: UserInput!) { createUser(input: $input) { id name } }
Purpose: Establish persistent connections to receive real-time data when events occur. Equivalent to WebSockets or Server-Sent Events.
Characteristics: Maintains an active connection; pushes data from server to client; requires transport layer like WebSockets.
Implementation: Usually uses WebSockets (Apollo) or SSE; supports filtering via arguments.
Use Cases: Live feeds, chat applications, real-time dashboards, collaborative editing.
Example: subscription OnUserCreated { userCreated { id name } }
Query names: Use nouns describing the data being fetched (e.g., GetUser, ListProducts, SearchPosts).
Mutation names: Use verbs describing the action (e.g., CreateUser, UpdatePost, DeleteComment).
Subscription names: Use past-tense event names (e.g., UserCreated, MessageAdded, StatusChanged).
Anonymous operations: Allowed but discouraged in production; named operations enable better debugging and performance tracking.
The three operation types differ in how they are executed. Queries can be executed in parallel, making them efficient for fetching independent data. Mutations are executed serially to prevent race conditions when multiple mutations affect related data. Subscriptions maintain a persistent connection and deliver data asynchronously as events occur. Understanding these execution semantics is critical for designing performant GraphQL APIs.