4

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?

His
  • 5,891
  • 15
  • 61
  • 82

1 Answers1

4

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

Lin Du
  • 88,126
  • 95
  • 281
  • 483
  • 1
    I think this solution doesn't work anymore, `this.context.dataSources` is empty in my case :/ – hannojg Jun 10 '21 at 09:21
  • Ah sorry, i was just checking `this.context.dataSources` in the initialize function of the `RESTDataSource` class where it was undefined. When using `this.context.dataSources` from inside the class's functions, it works :) – hannojg Jun 10 '21 at 09:26