0
# Internal APIs (Advanced)
1
2
Internal HTTP transport utilities for custom exchange development and advanced use cases. These APIs provide low-level control over GraphQL HTTP requests.
3
4
⚠️ **Warning**: These are internal APIs intended for advanced use cases and custom exchange development. They may change between minor versions.
5
6
## Capabilities
7
8
### HTTP Request Body Creation
9
10
Create GraphQL over HTTP compliant request bodies.
11
12
```typescript { .api }
13
/**
14
* Abstract definition of the JSON data sent during GraphQL HTTP POST requests
15
*/
16
interface FetchBody {
17
query?: string;
18
documentId?: string;
19
operationName: string | undefined;
20
variables: undefined | Record<string, any>;
21
extensions: undefined | Record<string, any>;
22
}
23
24
/**
25
* Creates a GraphQL over HTTP compliant JSON request body
26
* @param request - GraphQL request object
27
* @returns FetchBody for HTTP transport
28
*/
29
function makeFetchBody<Data = any, Variables extends AnyVariables = AnyVariables>(
30
request: Omit<GraphQLRequest<Data, Variables>, 'key'>
31
): FetchBody;
32
```
33
34
**Usage Examples:**
35
36
```typescript
37
import { makeFetchBody, createRequest, gql } from "@urql/core/internal";
38
39
const query = gql`
40
query GetUser($id: ID!) {
41
user(id: $id) { id name }
42
}
43
`;
44
45
const request = createRequest(query, { id: "123" });
46
const body = makeFetchBody(request);
47
48
console.log(body);
49
// {
50
// query: "query GetUser($id: ID!) { user(id: $id) { id name } }",
51
// operationName: "GetUser",
52
// variables: { id: "123" },
53
// extensions: undefined
54
// }
55
```
56
57
### URL Generation for GET Requests
58
59
Generate URLs for GraphQL HTTP GET requests with query parameter serialization.
60
61
```typescript { .api }
62
/**
63
* Creates a URL that will be called for a GraphQL HTTP request
64
* @param operation - Operation for which to make the request
65
* @param body - FetchBody which may be serialized into URL parameters
66
* @returns Complete URL for the GraphQL request
67
*/
68
function makeFetchURL(operation: Operation, body?: FetchBody): string;
69
```
70
71
**Usage Examples:**
72
73
```typescript
74
import { makeFetchURL, makeFetchBody, makeOperation } from "@urql/core/internal";
75
76
// Create operation with GET preference
77
const operation = makeOperation('query', request, {
78
url: "https://api.example.com/graphql",
79
preferGetMethod: true,
80
requestPolicy: 'cache-first'
81
});
82
83
const body = makeFetchBody(request);
84
const url = makeFetchURL(operation, body);
85
86
console.log(url);
87
// "https://api.example.com/graphql?query=query%20GetUser...&variables=%7B%22id%22%3A%22123%22%7D"
88
```
89
90
### Fetch Options Creation
91
92
Create RequestInit objects with proper headers and configuration for GraphQL requests.
93
94
```typescript { .api }
95
/**
96
* Creates a RequestInit object for a given Operation
97
* @param operation - Operation for which to make the request
98
* @param body - FetchBody which is added to options if not a GET request
99
* @returns RequestInit for use with fetch API
100
*/
101
function makeFetchOptions(operation: Operation, body?: FetchBody): RequestInit;
102
```
103
104
**Usage Examples:**
105
106
```typescript
107
import { makeFetchOptions, makeFetchBody } from "@urql/core/internal";
108
109
const options = makeFetchOptions(operation, body);
110
111
console.log(options);
112
// {
113
// method: "POST",
114
// headers: {
115
// "accept": "application/graphql-response+json, application/json, ...",
116
// "content-type": "application/json"
117
// },
118
// body: '{"query":"...","variables":{"id":"123"}}'
119
// }
120
121
// Use with custom transport
122
const response = await fetch(url, options);
123
```
124
125
### HTTP Transport Source
126
127
Stream-based HTTP transport with support for incremental delivery, subscriptions, and multipart responses.
128
129
```typescript { .api }
130
/**
131
* Creates a Wonka source for GraphQL HTTP transport
132
* @param operation - Operation to execute
133
* @param url - Target URL for the request
134
* @param fetchOptions - RequestInit options for the request
135
* @returns Source stream of OperationResults
136
*/
137
function makeFetchSource(
138
operation: Operation,
139
url: string,
140
fetchOptions: RequestInit
141
): Source<OperationResult>;
142
```
143
144
**Usage Examples:**
145
146
```typescript
147
import { makeFetchSource, makeFetchURL, makeFetchOptions, makeFetchBody } from "@urql/core/internal";
148
import { pipe, subscribe } from 'wonka';
149
150
// Create custom fetch-based exchange
151
const customFetchExchange = ({ forward }) => {
152
return operations$ => {
153
return pipe(
154
operations$,
155
mergeMap(operation => {
156
if (operation.kind === 'teardown') {
157
return empty;
158
}
159
160
const body = makeFetchBody(operation);
161
const url = makeFetchURL(operation, body);
162
const fetchOptions = makeFetchOptions(operation, body);
163
164
return makeFetchSource(operation, url, fetchOptions);
165
})
166
);
167
};
168
};
169
```
170
171
## Advanced Integration
172
173
### Custom Exchange with Internal APIs
174
175
Build a custom exchange using internal APIs for fine-grained control:
176
177
```typescript
178
import {
179
makeFetchBody,
180
makeFetchURL,
181
makeFetchOptions,
182
makeFetchSource
183
} from "@urql/core/internal";
184
import { pipe, mergeMap, empty, fromValue } from 'wonka';
185
186
const advancedFetchExchange = ({ forward }) => {
187
return operations$ => {
188
return pipe(
189
operations$,
190
mergeMap(operation => {
191
if (operation.kind === 'teardown') {
192
return empty;
193
}
194
195
// Custom body manipulation
196
const body = makeFetchBody(operation);
197
198
// Add custom extensions
199
if (operation.context.customExtension) {
200
body.extensions = {
201
...body.extensions,
202
custom: operation.context.customExtension
203
};
204
}
205
206
// Custom URL generation with caching logic
207
const url = makeFetchURL(operation, body);
208
209
// Custom fetch options with retry logic
210
const fetchOptions = makeFetchOptions(operation, body);
211
212
// Add custom headers for authentication
213
fetchOptions.headers = {
214
...fetchOptions.headers,
215
'x-request-id': generateRequestId(),
216
};
217
218
return makeFetchSource(operation, url, fetchOptions);
219
})
220
);
221
};
222
};
223
```
224
225
## Import Paths
226
227
```typescript
228
// Internal APIs must be imported from the internal path
229
import {
230
makeFetchBody,
231
makeFetchURL,
232
makeFetchOptions,
233
makeFetchSource,
234
type FetchBody
235
} from "@urql/core/internal";
236
```
237
238
## Protocol Support
239
240
The internal HTTP transport supports:
241
242
- **GraphQL over HTTP**: Standard JSON POST/GET requests
243
- **Incremental Delivery**: `@defer` and `@stream` directives
244
- **GraphQL over SSE**: Server-sent events for subscriptions
245
- **Multipart Responses**: Mixed content-type responses
246
- **File Uploads**: GraphQL multipart request spec
247
- **Persisted Queries**: Automatic persisted queries with GET requests
248
249
These protocols are handled automatically based on the server response content-type and operation characteristics.