0
# GraphQL Operations
1
2
Execute GraphQL queries, mutations, and subscriptions with full type safety and reactive streams. Operations provide both Promise-based and stream-based APIs for handling GraphQL requests.
3
4
## Capabilities
5
6
### Query Operations
7
8
Execute GraphQL queries with caching support and synchronous cache reads.
9
10
```typescript { .api }
11
/**
12
* Execute a GraphQL query operation
13
* @param query - GraphQL document or query string
14
* @param variables - Variables for the query
15
* @param context - Optional operation context overrides
16
* @returns OperationResultSource with query results
17
*/
18
query<Data = any, Variables extends AnyVariables = AnyVariables>(
19
query: DocumentInput<Data, Variables>,
20
variables: Variables,
21
context?: Partial<OperationContext>
22
): OperationResultSource<OperationResult<Data, Variables>>;
23
24
/**
25
* Read cached query result synchronously
26
* @param query - GraphQL document or query string
27
* @param variables - Variables for the query
28
* @param context - Optional operation context overrides
29
* @returns Cached result or null if not available
30
*/
31
readQuery<Data = any, Variables extends AnyVariables = AnyVariables>(
32
query: DocumentInput<Data, Variables>,
33
variables: Variables,
34
context?: Partial<OperationContext>
35
): OperationResult<Data, Variables> | null;
36
37
/**
38
* Execute query from a pre-created GraphQLRequest
39
* @param request - Pre-created GraphQL request
40
* @param opts - Optional operation context overrides
41
* @returns OperationResultSource with query results
42
*/
43
executeQuery<Data = any, Variables extends AnyVariables = AnyVariables>(
44
request: GraphQLRequest<Data, Variables>,
45
opts?: Partial<OperationContext> | undefined
46
): OperationResultSource<OperationResult<Data, Variables>>;
47
```
48
49
**Usage Examples:**
50
51
```typescript
52
import { createClient, gql, cacheExchange, fetchExchange } from "@urql/core";
53
54
const client = createClient({
55
url: "https://api.example.com/graphql",
56
exchanges: [cacheExchange, fetchExchange],
57
});
58
59
const GetUserQuery = gql`
60
query GetUser($id: ID!) {
61
user(id: $id) {
62
id
63
name
64
65
}
66
}
67
`;
68
69
// Promise-based query execution
70
const result = await client.query(GetUserQuery, { id: "123" }).toPromise();
71
if (result.error) {
72
console.error("Query failed:", result.error);
73
} else {
74
console.log("User:", result.data.user);
75
}
76
77
// Stream-based query (for cache updates)
78
const { unsubscribe } = client.query(GetUserQuery, { id: "123" }).subscribe(result => {
79
if (result.data) {
80
console.log("User data updated:", result.data.user);
81
}
82
});
83
84
// Check cache synchronously
85
const cached = client.readQuery(GetUserQuery, { id: "123" });
86
if (cached && !cached.stale) {
87
console.log("Fresh cached data:", cached.data.user);
88
}
89
```
90
91
### Mutation Operations
92
93
Execute GraphQL mutations with automatic cache invalidation.
94
95
```typescript { .api }
96
/**
97
* Execute a GraphQL mutation operation
98
* @param query - GraphQL document or mutation string
99
* @param variables - Variables for the mutation
100
* @param context - Optional operation context overrides
101
* @returns OperationResultSource with mutation results
102
*/
103
mutation<Data = any, Variables extends AnyVariables = AnyVariables>(
104
query: DocumentInput<Data, Variables>,
105
variables: Variables,
106
context?: Partial<OperationContext>
107
): OperationResultSource<OperationResult<Data, Variables>>;
108
109
/**
110
* Execute mutation from a pre-created GraphQLRequest
111
* @param request - Pre-created GraphQL request
112
* @param opts - Optional operation context overrides
113
* @returns OperationResultSource with mutation results
114
*/
115
executeMutation<Data = any, Variables extends AnyVariables = AnyVariables>(
116
request: GraphQLRequest<Data, Variables>,
117
opts?: Partial<OperationContext> | undefined
118
): OperationResultSource<OperationResult<Data, Variables>>;
119
```
120
121
**Usage Examples:**
122
123
```typescript
124
const UpdateUserMutation = gql`
125
mutation UpdateUser($id: ID!, $input: UserInput!) {
126
updateUser(id: $id, input: $input) {
127
id
128
name
129
130
updatedAt
131
}
132
}
133
`;
134
135
// Execute mutation
136
const result = await client.mutation(UpdateUserMutation, {
137
id: "123",
138
input: { name: "New Name", email: "new@example.com" }
139
}).toPromise();
140
141
if (result.error) {
142
console.error("Mutation failed:", result.error);
143
} else {
144
console.log("User updated:", result.data.updateUser);
145
}
146
147
// Mutation with cache invalidation hints
148
await client.mutation(
149
UpdateUserMutation,
150
{ id: "123", input: { name: "Updated Name" } },
151
{ additionalTypenames: ['User'] }
152
).toPromise();
153
```
154
155
### Subscription Operations
156
157
Execute GraphQL subscriptions for real-time data updates.
158
159
```typescript { .api }
160
/**
161
* Execute a GraphQL subscription operation
162
* @param query - GraphQL document or subscription string
163
* @param variables - Variables for the subscription
164
* @param context - Optional operation context overrides
165
* @returns OperationResultSource with subscription results
166
*/
167
subscription<Data = any, Variables extends AnyVariables = AnyVariables>(
168
query: DocumentInput<Data, Variables>,
169
variables: Variables,
170
context?: Partial<OperationContext>
171
): OperationResultSource<OperationResult<Data, Variables>>;
172
173
/**
174
* Execute subscription from a pre-created GraphQLRequest
175
* @param request - Pre-created GraphQL request
176
* @param opts - Optional operation context overrides
177
* @returns OperationResultSource with subscription results
178
*/
179
executeSubscription<Data = any, Variables extends AnyVariables = AnyVariables>(
180
request: GraphQLRequest<Data, Variables>,
181
opts?: Partial<OperationContext> | undefined
182
): OperationResultSource<OperationResult<Data, Variables>>;
183
```
184
185
**Usage Examples:**
186
187
```typescript
188
import { pipe, subscribe } from 'wonka';
189
190
const ChatMessagesSubscription = gql`
191
subscription ChatMessages($roomId: ID!) {
192
messageAdded(roomId: $roomId) {
193
id
194
text
195
user {
196
id
197
name
198
}
199
createdAt
200
}
201
}
202
`;
203
204
// Subscribe to real-time updates
205
const { unsubscribe } = pipe(
206
client.subscription(ChatMessagesSubscription, { roomId: "room-123" }),
207
subscribe(result => {
208
if (result.data) {
209
console.log("New message:", result.data.messageAdded);
210
}
211
if (result.error) {
212
console.error("Subscription error:", result.error);
213
}
214
})
215
);
216
217
// Unsubscribe when done
218
setTimeout(() => unsubscribe(), 30000);
219
```
220
221
### Low-Level Operation Management
222
223
Advanced operation creation and execution for custom use cases.
224
225
```typescript { .api }
226
/**
227
* Create an operation from a request and context
228
* @param kind - Type of GraphQL operation
229
* @param request - GraphQL request object
230
* @param opts - Optional context overrides
231
* @returns Created operation
232
*/
233
createRequestOperation<Data = any, Variables extends AnyVariables = AnyVariables>(
234
kind: OperationType,
235
request: GraphQLRequest<Data, Variables>,
236
opts?: Partial<OperationContext> | undefined
237
): Operation<Data, Variables>;
238
239
/**
240
* Execute an operation and return result source
241
* @param operation - Operation to execute
242
* @returns OperationResultSource with results
243
*/
244
executeRequestOperation<Data = any, Variables extends AnyVariables = AnyVariables>(
245
operation: Operation<Data, Variables>
246
): OperationResultSource<OperationResult<Data, Variables>>;
247
248
/**
249
* Re-execute an operation if it has active consumers
250
* @param operation - Operation to re-execute
251
*/
252
reexecuteOperation(operation: Operation): void;
253
```
254
255
**Usage Examples:**
256
257
```typescript
258
import { createRequest } from "@urql/core";
259
260
// Create request and operation manually
261
const request = createRequest(GetUserQuery, { id: "123" });
262
const operation = client.createRequestOperation('query', request, {
263
requestPolicy: 'network-only'
264
});
265
266
// Execute the operation
267
const result = await client.executeRequestOperation(operation).toPromise();
268
269
// Re-execute operation (useful in exchanges)
270
client.reexecuteOperation(operation);
271
```
272
273
## Types
274
275
### Operation Types
276
277
```typescript { .api }
278
type OperationType = 'subscription' | 'query' | 'mutation' | 'teardown';
279
280
interface Operation<Data = any, Variables extends AnyVariables = AnyVariables>
281
extends GraphQLRequest<Data, Variables> {
282
readonly kind: OperationType;
283
context: OperationContext;
284
}
285
286
interface GraphQLRequest<Data = any, Variables extends AnyVariables = AnyVariables> {
287
key: number;
288
query: DocumentNode | PersistedDocument | TypedDocumentNode<Data, Variables>;
289
variables: Variables;
290
extensions?: RequestExtensions | undefined;
291
}
292
```
293
294
### Result Types
295
296
```typescript { .api }
297
interface OperationResult<Data = any, Variables extends AnyVariables = AnyVariables> {
298
/** The operation this result is for */
299
operation: Operation<Data, Variables>;
300
/** GraphQL response data */
301
data?: Data;
302
/** Combined GraphQL and network errors */
303
error?: CombinedError;
304
/** Additional response metadata */
305
extensions?: Record<string, any>;
306
/** Whether result is stale and will be updated */
307
stale: boolean;
308
/** Whether more results will follow (subscriptions/streaming) */
309
hasNext: boolean;
310
}
311
312
type OperationResultSource<T extends OperationResult> = Source<T> &
313
PromiseLike<T> & {
314
/** Convert to Promise for single result */
315
toPromise(): Promise<T>;
316
/** Subscribe to result stream */
317
subscribe(onResult: (value: T) => void): Subscription;
318
};
319
```
320
321
### Document Input Types
322
323
```typescript { .api }
324
type DocumentInput<Result = { [key: string]: any }, Variables = { [key: string]: any }> =
325
string | DocumentNode | TypedDocumentNode<Result, Variables>;
326
327
interface TypedDocumentNode<Result = { [key: string]: any }, Variables = { [key: string]: any }>
328
extends DocumentNode {
329
__apiType?: (variables: Variables) => Result;
330
__ensureTypesOfVariablesAndResultMatching?: (variables: Variables) => Result;
331
}
332
333
type AnyVariables = { [prop: string]: any } | void | undefined;
334
```
335
336
### Request Extensions
337
338
```typescript { .api }
339
interface RequestExtensions {
340
/** Automatic Persisted Queries support */
341
persistedQuery?: PersistedRequestExtensions;
342
[extension: string]: any;
343
}
344
345
interface PersistedRequestExtensions {
346
version?: 1;
347
sha256Hash: string;
348
miss?: boolean;
349
}
350
```
351
352
### Operation Instance
353
354
```typescript { .api }
355
type OperationInstance = number & {
356
readonly _opaque: unique symbol;
357
};
358
```