Apollo HTTP Data Source

0.21.0 · active · verified Tue Apr 21

apollo-datasource-http is an optimized HTTP data source for Apollo Server, designed to enhance performance when fetching JSON data from REST APIs. Currently at version 0.21.0, it is actively developed with a frequent release cadence, though it explicitly warns that releases are pre-1.0 and may introduce breaking changes. Its key differentiators include leveraging the high-performance Undici HTTP client (claiming up to 60% faster than `apollo-datasource-rest`), integrated request deduplication via LRU caching, configurable request caching with TTL, and `stale-if-error` capabilities. It also supports `AbortController` for manual request cancellation and integrates with Apollo Cache Storage backends for advanced caching strategies. This data source aims to provide a robust and efficient solution for connecting Apollo Server to external HTTP services, offering fine-grained control over request lifecycle and caching behavior through a hook-based API.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates how to extend `HTTPDataSource` to create a custom data source, configure it with `undici.Pool`, and implement methods for making cached GET and POST requests within an Apollo Server setup.

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import { Pool } from 'undici';
import { HTTPDataSource } from 'apollo-datasource-http';

const typeDefs = `#graphql
  type Movie {
    id: ID!
    name: String
  }

  type Query {
    movie(id: ID!): Movie
  }

  type Mutation {
    createMovie(name: String!): Movie
  }
`;

const baseURL = 'https://movies-api.example.com'; // Replace with your actual API base URL
const pool = new Pool(baseURL);

class MoviesAPI extends HTTPDataSource {
  constructor(baseURL: string, pool: Pool) {
    super(baseURL, { pool });
  }

  async createMovie(name: string) {
    return this.post('/movies', {
      body: { name }
    });
  }

  async getMovie(id: string) {
    return this.get(`/movies/${id}`, {
      context: { tracingName: 'getMovie' },
      requestCache: {
        maxTtl: 10 * 60, // 10min, will respond for 10min with the cached result
        maxTtlIfError: 30 * 60 // 30min, will respond with cached response in case of error
      }
    });
  }
}

const resolvers = {
  Query: {
    movie: async (_, { id }, { dataSources }) => {
      return dataSources.moviesAPI.getMovie(id);
    }
  },
  Mutation: {
    createMovie: async (_, { name }, { dataSources }) => {
      return dataSources.moviesAPI.createMovie(name);
    }
  }
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

startStandaloneServer(server, {
  listen: { port: 4000 },
  context: async ({ req, res }) => ({
    dataSources: {
      moviesAPI: new MoviesAPI(baseURL, pool),
    },
  }),
}).then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`);
});

view raw JSON →