javascriptgraphqlapolloapollo-serverrestdatasource

Apollo RESTDataSource calling other RESTDataSource?


Say I have an 2 API classes that extend RESTDataSource:

class MoviesAPI extends RESTDataSource {
async getMovies() {}
}

class SongsAPI extends RESTDataSource {
async getSongs() {}
}

How can I call getSongs from getMovies within the existing Apollo server context?


Solution

  • You can get the apollo server context via this.context in the datasource class and get dataSources via this.context.dataSources.

    E.g.

    server.ts:

    import { ApolloServer, gql } from 'apollo-server';
    import { MoviesAPI } from './MoviesAPI';
    import { SongsAPI } from './SongsAPI';
    
    const typeDefs = gql`
      type Query {
        movies: String
      }
    `;
    const resolvers = {
      Query: {
        movies: (_, __, { dataSources }) => {
          return dataSources.moviesAPI.getMovies();
        },
      },
    };
    
    const server = new ApolloServer({
      typeDefs,
      resolvers,
      dataSources: () => {
        return {
          moviesAPI: new MoviesAPI(),
          songsAPI: new SongsAPI(),
        };
      },
    });
    
    server.listen().then(({ url }) => {
      console.log(`Apollo server is listening on ${url}`);
    });
    

    MoviesAPI.ts:

    import { RESTDataSource } from 'apollo-datasource-rest';
    
    export class MoviesAPI extends RESTDataSource {
      async getMovies() {
        const songs = await this.context.dataSources.songsAPI.getSongs();
        const movies = ['a', 'b'];
        return JSON.stringify({ movies, songs });
      }
    }
    

    SongsAPI.ts:

    import { RESTDataSource } from 'apollo-datasource-rest';
    
    export class SongsAPI extends RESTDataSource {
      async getSongs() {
        return ['x', 'y'];
      }
    }
    

    Send a GraphQL query from the client-side:

    query{
      movies
    }
    

    Response payload:

    {
      "data": {
        "movies": "{\"movies\":[\"a\",\"b\"],\"songs\":[\"x\",\"y\"]}"
      }
    }
    

    Package versions: "apollo-datasource-rest": "^0.8.1", "apollo-server": "^2.12.0"

    source code: https://github.com/mrdulin/apollo-graphql-tutorial/tree/master/src/stackoverflow/61425326