or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

batch-operations.mderror-handling.mdgraphql-client.mdindex.mdraw-requests.mdstatic-functions.md
tile.json

raw-requests.mddocs/

Raw Requests

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.

Capabilities

Raw Request Function

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);
}

GraphQL Client Raw Request Method

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);
}

Response Structure

GraphQL Client Response

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[];
}

GraphQL Error Structure

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;
  };
}

Use Cases and Best Practices

Error Handling with Raw Requests

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;
  }
}

Accessing Server Extensions

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);
}

Debugging and Development

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;
}

Supporting Types

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];