Raw request functionality provides access to the complete GraphQL response including errors, extensions, headers, and status codes. This is essential for applications requiring full response introspection, custom error handling, or access to GraphQL extensions.
Static function for sending GraphQL queries with complete response metadata.
/**
* Send a GraphQL query and receive the complete raw response
* @param url - GraphQL endpoint URL
* @param query - GraphQL query string
* @param variables - Optional variables for the query
* @param requestHeaders - Optional headers for the request
* @returns Promise resolving to complete response with metadata
*/
function rawRequest<T, V extends Variables = Variables>(
url: string,
query: string,
variables?: V,
requestHeaders?: HeadersInit
): Promise<GraphQLClientResponse<T>>;
/**
* Send a raw GraphQL request using an options object
* @param options - Complete raw request configuration
* @returns Promise resolving to complete response with metadata
*/
function rawRequest<T, V extends Variables = Variables>(
options: RawRequestExtendedOptions<V>
): Promise<GraphQLClientResponse<T>>;
interface RawRequestExtendedOptions<V extends Variables = Variables> {
url: string;
query: string;
requestHeaders?: HeadersInit;
signal?: RequestInit["signal"];
variables?: V;
}Usage Examples:
import { rawRequest, gql } from "graphql-request";
// Basic raw request
const queryString = `
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
`;
const response = await rawRequest(
"https://api.example.com/graphql",
queryString,
{ id: "123" }
);
console.log("Status:", response.status);
console.log("Headers:", response.headers);
console.log("Data:", response.data);
console.log("Errors:", response.errors);
console.log("Extensions:", response.extensions);
// Using options object
const responseWithOptions = await rawRequest({
url: "https://api.example.com/graphql",
query: queryString,
variables: { id: "123" },
requestHeaders: {
authorization: "Bearer TOKEN",
"x-request-id": "req-456",
},
});
// Handling partial errors with raw response
const mutationString = `
mutation CreateUsers($users: [CreateUserInput!]!) {
createUsers(input: $users) {
id
name
errors
}
}
`;
const mutationResponse = await rawRequest(
"https://api.example.com/graphql",
mutationString,
{
users: [
{ name: "John", email: "john@example.com" },
{ name: "", email: "invalid" }, // This might cause partial errors
],
}
);
if (mutationResponse.errors) {
console.log("GraphQL errors occurred:", mutationResponse.errors);
}
if (mutationResponse.data) {
console.log("Partial data received:", mutationResponse.data);
}Instance method on GraphQLClient for raw requests with client configuration.
/**
* Send a GraphQL query using the client and receive raw response
* @param query - GraphQL query string
* @param variables - Optional variables for the query
* @param requestHeaders - Optional headers for this request
* @returns Promise resolving to complete response with metadata
*/
rawRequest<T, V extends Variables = Variables>(
query: string,
variables?: V,
requestHeaders?: HeadersInit
): Promise<GraphQLClientResponse<T>>;
/**
* Send a raw GraphQL request using options object
* @param options - Raw request options
* @returns Promise resolving to complete response with metadata
*/
rawRequest<T, V extends Variables = Variables>(
options: RawRequestOptions<V>
): Promise<GraphQLClientResponse<T>>;
interface RawRequestOptions<V extends Variables = Variables> {
query: string;
requestHeaders?: HeadersInit;
signal?: RequestInit["signal"];
variables?: V;
}Usage Examples:
import { GraphQLClient } from "graphql-request";
const client = new GraphQLClient("https://api.example.com/graphql", {
headers: {
authorization: "Bearer TOKEN",
},
});
const queryString = `
{
posts {
id
title
author {
name
}
}
}
`;
// Raw request with client
const response = await client.rawRequest(queryString);
// Check response metadata
if (response.status === 200) {
console.log("Request successful");
console.log("Response time:", response.headers.get("x-response-time"));
}
// Handle GraphQL errors while still accessing data
if (response.errors && response.errors.length > 0) {
console.warn("GraphQL errors:", response.errors);
// Still process partial data if available
if (response.data) {
console.log("Partial data:", response.data);
}
}
// Access extensions for debugging
if (response.extensions) {
console.log("Query complexity:", response.extensions.complexity);
console.log("Execution time:", response.extensions.executionTime);
}Complete response object returned by raw request functions.
interface GraphQLClientResponse<Data> {
/** HTTP status code of the response */
status: number;
/** Response headers from the server */
headers: Headers;
/** GraphQL response data (may be null if errors occurred) */
data: Data;
/** GraphQL extensions (server-specific metadata) */
extensions?: unknown;
/** Array of GraphQL errors (may be present even with successful data) */
errors?: GraphQLError[];
}Standard GraphQL error format as defined by the GraphQL specification.
interface GraphQLError {
/** Error message */
message: string;
/** Source locations where the error occurred */
locations?: Array<{
line: number;
column: number;
}>;
/** Path to the field that caused the error */
path?: Array<string | number>;
/** Additional error information */
extensions?: {
code?: string;
exception?: {
stacktrace?: string[];
};
[key: string]: any;
};
}Raw requests are ideal when you need granular control over error handling:
import { rawRequest, ClientError } from "graphql-request";
async function robustGraphQLRequest(query: string, variables?: any) {
try {
const response = await rawRequest(
"https://api.example.com/graphql",
query,
variables
);
// Check for network/HTTP errors
if (response.status >= 400) {
throw new Error(`HTTP error: ${response.status}`);
}
// Handle GraphQL errors
if (response.errors && response.errors.length > 0) {
const criticalErrors = response.errors.filter(
error => error.extensions?.code === "CRITICAL"
);
if (criticalErrors.length > 0) {
throw new Error(`Critical GraphQL error: ${criticalErrors[0].message}`);
}
// Log non-critical errors but continue
console.warn("Non-critical GraphQL errors:", response.errors);
}
return response.data;
} catch (error) {
if (error instanceof ClientError) {
// Handle graphql-request specific errors
console.error("GraphQL request failed:", error.response);
} else {
// Handle other errors (network, parsing, etc.)
console.error("Request error:", error);
}
throw error;
}
}Many GraphQL servers provide additional metadata via extensions:
import { rawRequest } from "graphql-request";
const response = await rawRequest(
"https://api.example.com/graphql",
`
query ExpensiveQuery {
allUsers {
id
posts {
comments {
author {
profile
}
}
}
}
}
`
);
// Access server-provided metrics
if (response.extensions) {
console.log("Query cost:", response.extensions.queryCost);
console.log("Rate limit remaining:", response.extensions.rateLimit?.remaining);
console.log("Cache status:", response.extensions.cacheStatus);
console.log("Execution time:", response.extensions.timing?.total);
}Raw requests are valuable for debugging and development:
import { rawRequest } from "graphql-request";
const DEBUG_MODE = process.env.NODE_ENV === "development";
async function debugGraphQLRequest(query: string, variables?: any) {
const response = await rawRequest(
"https://api.example.com/graphql",
query,
variables
);
if (DEBUG_MODE) {
console.group("GraphQL Request Debug");
console.log("Status:", response.status);
console.log("Headers:", Object.fromEntries(response.headers.entries()));
console.log("Data:", response.data);
console.log("Errors:", response.errors);
console.log("Extensions:", response.extensions);
console.groupEnd();
}
return response;
}type Variables = object;
type VariablesAndRequestHeadersArgs<V extends Variables> = V extends Record<any, never>
? [variables?: V, requestHeaders?: HeadersInit]
: keyof RemoveIndex<V> extends never
? [variables?: V, requestHeaders?: HeadersInit]
: [variables: V, requestHeaders?: HeadersInit];