Apollo Datasource SWR • latest version release

npm status

An implementation of Apollo Datasource to support SWR caching mechanism.

Features:

  • SWR caching
  • Request deduplication

Installation

npm i -S apollo-datasource-swr

Usage

Make sure to enable decorator support by adding this line in your tsconfig.json:

{
  "compilerOptions": {
    "experimentalDecorators": true,    // <-- add this
    ...
  },
}
import fetch from "node-fetch";
import { UserInputError } from "apollo-server-express";
import { SWRDataSource } from "apollo-datasource-swr"; // <-- import SWRDataSource

// datasources/movies.ts
class MoviesAPI extends SWRDataSource<Context> {
  private endpoint: string;

  constructor(endpoint: string) {
    super({
      // see https://datatracker.ietf.org/doc/html/rfc5861#section-3
      // for explanation of how MaxAge and SWR behave.
      ttlMaxAge: 10, // MaxAge in seconds.
      ttlSWR: 3600, // SWR TTL in seconds.

      logger: getLogger(), // apollo compatible Logger
    });
    this.endpoint = endpoint;
  }

  @SWRDataSource.useSWR // <-- add this decorator to your fetcher
  async getMovie(movieId: string) {
    const res = await fetch(`${this.endpoint}/movies/${movieId}`);
    const body = await res.json();
    return body as Movie;
  }

  @SWRDataSource.useSWR // <-- add as many methods as you like!
  async getTheatre(theatreId: string) {
    // Apollo request context is available: this.context
    if (!this.context.auth) {
      throw new UserInputError("Not authenticated");
    }

    const res = await fetch(`${this.endpoint}/theatre/${theatreId}`);
    const body = await res.json();
    return body as Theatre;
  }
}

// -------------
// main.ts
// use the data source:
const server = new ApolloServer({
  typeDefs,
  resolvers,
  dataSources: () => {
    return {
      moviesAPI: new MoviesAPI(), // <-- add it in your Apollo Server
    };
  },
});