Apollo Engine Loader is a GraphQL schema loader that fetches GraphQL schemas from Apollo Engine (now Apollo Studio) using API keys and graph identifiers. It provides both asynchronous and synchronous loading capabilities, integrating seamlessly with the GraphQL Tools ecosystem for schema manipulation and validation workflows.
npm install @graphql-tools/apollo-engine-loaderimport { ApolloEngineLoader, ApolloEngineOptions, SCHEMA_QUERY } from "@graphql-tools/apollo-engine-loader";For CommonJS:
const { ApolloEngineLoader, ApolloEngineOptions, SCHEMA_QUERY } = require("@graphql-tools/apollo-engine-loader");import { ApolloEngineLoader } from "@graphql-tools/apollo-engine-loader";
const loader = new ApolloEngineLoader();
// Configure Apollo Engine connection
const options = {
engine: {
apiKey: "your-apollo-api-key",
endpoint: "https://engine-graphql.apollographql.com/api/graphql" // optional, uses default
},
graph: "your-graph-id",
variant: "current", // or "staging", etc.
headers: { // optional additional headers
"Custom-Header": "value"
}
};
// Load schema asynchronously
const sources = await loader.load("apollo-engine", options);
console.log(sources[0].document); // GraphQL schema SDL
// Load schema synchronously
const syncSources = loader.loadSync("apollo-engine", options);
console.log(syncSources[0].document); // GraphQL schema SDLConfiguration interface for Apollo Engine connections and schema loading.
interface ApolloEngineOptions extends BaseLoaderOptions {
/** Apollo Engine connection configuration */
engine: {
/** Optional Apollo Engine endpoint URL. Defaults to https://engine-graphql.apollographql.com/api/graphql */
endpoint?: string;
/** Required API key for Apollo Engine authentication */
apiKey: string;
};
/** Apollo graph identifier */
graph: string;
/** Apollo graph variant/tag (e.g., "current", "staging") */
variant: string;
/** Optional additional HTTP headers */
headers?: Record<string, string>;
}Usage Example:
const options: ApolloEngineOptions = {
engine: {
apiKey: process.env.APOLLO_KEY!,
endpoint: "https://engine-graphql.apollographql.com/api/graphql"
},
graph: "my-graph-id",
variant: "production",
headers: {
"Custom-User-Agent": "my-app/1.0.0"
}
};Main loader class implementing both asynchronous and synchronous GraphQL schema loading from Apollo Engine.
class ApolloEngineLoader implements Loader<ApolloEngineOptions> {
/**
* Check if the loader can handle the given pointer asynchronously
* @param ptr - Pointer to check (must be "apollo-engine")
* @returns Promise resolving to true if pointer equals "apollo-engine"
*/
canLoad(ptr: string): Promise<boolean>;
/**
* Check if the loader can handle the given pointer synchronously
* @param ptr - Pointer to check (must be "apollo-engine")
* @returns true if pointer equals "apollo-engine"
*/
canLoadSync(ptr: string): boolean;
/**
* Load GraphQL schema from Apollo Engine asynchronously
* @param pointer - Must be "apollo-engine"
* @param options - Apollo Engine configuration options
* @returns Promise resolving to array of GraphQL schema sources (or empty array if pointer invalid)
* @throws AggregateError if Apollo Engine API returns errors
*/
load(pointer: string, options: ApolloEngineOptions): Promise<Source[]>;
/**
* Load GraphQL schema from Apollo Engine synchronously
* @param pointer - Must be "apollo-engine"
* @param options - Apollo Engine configuration options
* @returns Array of GraphQL schema sources (or empty array if pointer invalid)
* @throws AggregateError if Apollo Engine API returns errors
*/
loadSync(pointer: string, options: ApolloEngineOptions): Source[];
/**
* @private
* Constructs fetch arguments for Apollo Engine API requests
* @param options - Apollo Engine configuration options
* @returns Tuple of [url, RequestInit] for fetch calls
*/
private getFetchArgs(options: ApolloEngineOptions): [string, RequestInit];
}Usage Examples:
const loader = new ApolloEngineLoader();
// Check if loader can handle pointer
const canLoad = await loader.canLoad("apollo-engine"); // true
const canLoadSync = loader.canLoadSync("apollo-engine"); // true
const cannotLoad = await loader.canLoad("file"); // false
// Async loading with error handling
try {
const sources = await loader.load("apollo-engine", {
engine: { apiKey: "valid-key" },
graph: "my-graph",
variant: "current"
});
console.log("Schema loaded:", sources[0].document);
} catch (error) {
if (error instanceof AggregateError) {
console.error("Apollo Engine errors:", error.errors);
}
}
// Sync loading
const sources = loader.loadSync("apollo-engine", {
engine: { apiKey: "valid-key" },
graph: "my-graph",
variant: "current"
});Internal GraphQL query used to fetch schema documents from Apollo Engine API.
/**
* @internal
* GraphQL query for fetching service schema by tag and ID from Apollo Engine
*/
const SCHEMA_QUERY: string;Default endpoint URL used when no custom endpoint is specified in options.
/**
* Default Apollo Engine GraphQL endpoint URL
*/
const DEFAULT_APOLLO_ENDPOINT: "https://engine-graphql.apollographql.com/api/graphql";The query structure:
query GetSchemaByTag($tag: String!, $id: ID!) {
service(id: $id) {
... on Service {
__typename
schema(tag: $tag) {
document
}
}
}
}The loader integrates with types from external GraphQL Tools packages:
// From @graphql-tools/utils
interface BaseLoaderOptions extends GraphQLParseOptions, BuildSchemaOptions {
cwd?: string;
ignore?: string | string[];
includeSources?: boolean;
}
interface GraphQLParseOptions {
noLocation?: boolean;
allowLegacySDLEmptyFields?: boolean;
allowLegacySDLImplementsInterfaces?: boolean;
experimentalFragmentVariables?: boolean;
commentDescriptions?: boolean;
}
interface BuildSchemaOptions {
assumeValidSDL?: boolean;
sort?: boolean;
}
interface Source {
document?: DocumentNode;
schema?: GraphQLSchema;
rawSDL?: string;
location?: string;
}
interface Loader<TOptions extends BaseLoaderOptions = BaseLoaderOptions> {
load(pointer: string, options?: TOptions): Promise<Source[] | null | never>;
loadSync?(pointer: string, options?: TOptions): Source[] | null | never;
}The loader throws AggregateError instances when Apollo Engine API returns errors:
try {
const sources = await loader.load("apollo-engine", options);
} catch (error) {
if (error instanceof AggregateError) {
// error.errors contains array of individual Apollo Engine errors
error.errors.forEach(err => console.error(err.message));
// error.message contains combined error message
console.error("Combined errors:", error.message);
}
}The loader uses https://engine-graphql.apollographql.com/api/graphql as the default Apollo Engine endpoint.
Requests include standard Apollo client identification headers:
x-api-key: Your API keyapollo-client-name: "Apollo Language Server"apollo-client-reference-id: "146d29c0-912c-46d3-b686-920e52586be6"apollo-client-version: "2.6.8"Content-Type: "application/json"Accept: "application/json"Additional headers can be specified via the headers option and will be merged with defaults.
Both sync and async loading methods require the exact string "apollo-engine" as the pointer parameter. Any other value will result in an empty array return.
The loader uses several key dependencies for HTTP requests and GraphQL processing:
loadSync functionalityparseGraphQLSDL, BaseLoaderOptions, Loader, and Source interfaces// Key external functions used
function parseGraphQLSDL(
pointer: string,
sdl: string,
options: BaseLoaderOptions
): Source;This loader integrates seamlessly with other GraphQL Tools packages:
import { loadSchema } from "@graphql-tools/load";
import { ApolloEngineLoader } from "@graphql-tools/apollo-engine-loader";
// Use with @graphql-tools/load
const schema = await loadSchema("apollo-engine", {
loaders: [new ApolloEngineLoader()],
engine: { apiKey: "your-key" },
graph: "your-graph",
variant: "current"
});