The shared core for the highly customizable and versatile GraphQL client
—
Internal HTTP transport utilities for custom exchange development and advanced use cases. These APIs provide low-level control over GraphQL HTTP requests.
⚠️ Warning: These are internal APIs intended for advanced use cases and custom exchange development. They may change between minor versions.
Create GraphQL over HTTP compliant request bodies.
/**
* Abstract definition of the JSON data sent during GraphQL HTTP POST requests
*/
interface FetchBody {
query?: string;
documentId?: string;
operationName: string | undefined;
variables: undefined | Record<string, any>;
extensions: undefined | Record<string, any>;
}
/**
* Creates a GraphQL over HTTP compliant JSON request body
* @param request - GraphQL request object
* @returns FetchBody for HTTP transport
*/
function makeFetchBody<Data = any, Variables extends AnyVariables = AnyVariables>(
request: Omit<GraphQLRequest<Data, Variables>, 'key'>
): FetchBody;Usage Examples:
import { makeFetchBody, createRequest, gql } from "@urql/core/internal";
const query = gql`
query GetUser($id: ID!) {
user(id: $id) { id name }
}
`;
const request = createRequest(query, { id: "123" });
const body = makeFetchBody(request);
console.log(body);
// {
// query: "query GetUser($id: ID!) { user(id: $id) { id name } }",
// operationName: "GetUser",
// variables: { id: "123" },
// extensions: undefined
// }Generate URLs for GraphQL HTTP GET requests with query parameter serialization.
/**
* Creates a URL that will be called for a GraphQL HTTP request
* @param operation - Operation for which to make the request
* @param body - FetchBody which may be serialized into URL parameters
* @returns Complete URL for the GraphQL request
*/
function makeFetchURL(operation: Operation, body?: FetchBody): string;Usage Examples:
import { makeFetchURL, makeFetchBody, makeOperation } from "@urql/core/internal";
// Create operation with GET preference
const operation = makeOperation('query', request, {
url: "https://api.example.com/graphql",
preferGetMethod: true,
requestPolicy: 'cache-first'
});
const body = makeFetchBody(request);
const url = makeFetchURL(operation, body);
console.log(url);
// "https://api.example.com/graphql?query=query%20GetUser...&variables=%7B%22id%22%3A%22123%22%7D"Create RequestInit objects with proper headers and configuration for GraphQL requests.
/**
* Creates a RequestInit object for a given Operation
* @param operation - Operation for which to make the request
* @param body - FetchBody which is added to options if not a GET request
* @returns RequestInit for use with fetch API
*/
function makeFetchOptions(operation: Operation, body?: FetchBody): RequestInit;Usage Examples:
import { makeFetchOptions, makeFetchBody } from "@urql/core/internal";
const options = makeFetchOptions(operation, body);
console.log(options);
// {
// method: "POST",
// headers: {
// "accept": "application/graphql-response+json, application/json, ...",
// "content-type": "application/json"
// },
// body: '{"query":"...","variables":{"id":"123"}}'
// }
// Use with custom transport
const response = await fetch(url, options);Stream-based HTTP transport with support for incremental delivery, subscriptions, and multipart responses.
/**
* Creates a Wonka source for GraphQL HTTP transport
* @param operation - Operation to execute
* @param url - Target URL for the request
* @param fetchOptions - RequestInit options for the request
* @returns Source stream of OperationResults
*/
function makeFetchSource(
operation: Operation,
url: string,
fetchOptions: RequestInit
): Source<OperationResult>;Usage Examples:
import { makeFetchSource, makeFetchURL, makeFetchOptions, makeFetchBody } from "@urql/core/internal";
import { pipe, subscribe } from 'wonka';
// Create custom fetch-based exchange
const customFetchExchange = ({ forward }) => {
return operations$ => {
return pipe(
operations$,
mergeMap(operation => {
if (operation.kind === 'teardown') {
return empty;
}
const body = makeFetchBody(operation);
const url = makeFetchURL(operation, body);
const fetchOptions = makeFetchOptions(operation, body);
return makeFetchSource(operation, url, fetchOptions);
})
);
};
};Build a custom exchange using internal APIs for fine-grained control:
import {
makeFetchBody,
makeFetchURL,
makeFetchOptions,
makeFetchSource
} from "@urql/core/internal";
import { pipe, mergeMap, empty, fromValue } from 'wonka';
const advancedFetchExchange = ({ forward }) => {
return operations$ => {
return pipe(
operations$,
mergeMap(operation => {
if (operation.kind === 'teardown') {
return empty;
}
// Custom body manipulation
const body = makeFetchBody(operation);
// Add custom extensions
if (operation.context.customExtension) {
body.extensions = {
...body.extensions,
custom: operation.context.customExtension
};
}
// Custom URL generation with caching logic
const url = makeFetchURL(operation, body);
// Custom fetch options with retry logic
const fetchOptions = makeFetchOptions(operation, body);
// Add custom headers for authentication
fetchOptions.headers = {
...fetchOptions.headers,
'x-request-id': generateRequestId(),
};
return makeFetchSource(operation, url, fetchOptions);
})
);
};
};// Internal APIs must be imported from the internal path
import {
makeFetchBody,
makeFetchURL,
makeFetchOptions,
makeFetchSource,
type FetchBody
} from "@urql/core/internal";The internal HTTP transport supports:
@defer and @stream directivesThese protocols are handled automatically based on the server response content-type and operation characteristics.
Install with Tessl CLI
npx tessl i tessl/npm-urql--core