An implementation of Apollo Datasource to support SWR caching mechanism.
Features:
- SWR caching
- Request deduplication
npm i -S apollo-datasource-swr
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
};
},
});