title | description |
---|---|
Fetching Data |
Using RESTDataSource to fetch data from REST APIs |
Data sources are classes that Apollo Server can use to encapsulate fetching data from a particular source, such as a database or a REST API. These classes help handle caching, deduplication, and errors while resolving operations.
Your server can use any number of different data sources. You don't have to use data sources to fetch data, but they're strongly recommended.
flowchart LR;
restAPI(REST API);
db(Database);
subgraph ApolloServer;
restDataSource(RESTDataSource);
DBDataSource(DBDataSource);
end
restDataSource --Fetches data--> restAPI;
DBDataSource --Fetches data--> db;
client(ApolloClient);
client --Sends query--> ApolloServer;
class restAPI,db secondary;
All data source implementations extend the generic DataSource
abstract class, which is included in the apollo-datasource
package. Subclasses of a DataSource
should define whatever logic is required to communicate with a particular store or API.
Apollo and the larger community maintain the following open-source implementations:
Do you maintain a
DataSource
implementation that isn't listed here? Please submit a PR to be added to the list!
Class | Source | For Use With |
---|---|---|
RESTDataSource |
Apollo | REST APIs (see below) |
HTTPDataSource |
Community | HTTP/REST APIs (newer community alternative to RESTDataSource ) |
SQLDataSource |
Community | SQL databases (via Knex.js) |
MongoDataSource |
Community | MongoDB |
CosmosDataSource |
Community | Azure Cosmos DB |
FirestoreDataSource |
Community | Cloud Firestore |
If none of these implementations applies to your use case, you can create your own custom DataSource
subclass.
Apollo does not provide official support for community-maintained libraries. We cannot guarantee that community-maintained libraries adhere to best practices, or that they will continue to be maintained. -->
You provide your DataSource
subclasses to the context
initialization function, like so:
//highlight-start
interface ContextValue {
dataSources: {
moviesAPI: MoviesAPI;
personalizationAPI: PersonalizationAPI;
};
}
//highlight-end
const server = new ApolloServer<ContextValue>({
typeDefs,
resolvers,
});
const { url } = await startStandaloneServer(server, {
context: async ({ req }) => {
return {
//highlight-start
// We create new instances of our data sources with each request
dataSources: {
moviesAPI: new MoviesAPI(),
personalizationAPI: new PersonalizationAPI(),
},
//highlight-end
};
},
});
console.log(`馃殌 Server ready at ${url}`);
Apollo Server calls the the context
initialization function for every incoming operation. This means:
- As shown above, with every operation
context
returns an object containing new instances of yourDataSource
subclasses (in this case,MoviesAPI
andPersonalizationAPI
). - These subclasses are accessible from the the
context
value argument that's passed between your server's resolvers. - The
context
function should create a new instance of each data source for each operation. If multiple operations share a single data source instance, you might accidentally combine results from multiple operations.
Your resolvers can now access your data sources from the shared context
object and use them to fetch data:
const resolvers = {
Query: {
movie: async (_, { id }, { dataSources }) => {
return dataSources.moviesAPI.getMovie(id);
},
mostViewedMovies: async (_, __, { dataSources }) => {
return dataSources.moviesAPI.getMostViewedMovies();
},
favorites: async (_, __, { dataSources }) => {
return dataSources.personalizationAPI.getFavorites();
},
},
};
By default, data source implementations use Apollo Server's in-memory cache to store the results of past fetches.
When you initialize Apollo Server, you can provide its constructor a different cache object that implements the KeyValueCache
interface. This enables you to back your cache with shared stores like Memcached or Redis.
const server = new ApolloServer({
typeDefs,
resolvers,
cache: new MyCustomKeyValueCache()
});
When running multiple instances of your server, you should use a shared cache backend. This enables one server instance to use the cached result from another instance.
Apollo Server supports using Memcached, Redis, or other cache backends via the keyv
package. For examples, see Configuring external caching.
You can also choose to implement your own cache backend. For more information, see Implementing your own cache backend.