Use Contentful as an Apollo Subgraph
Table of contents
Use Contentful as an Apollo Subgraph
You can use the Contentful GraphQL API as a subgraph in Apollo Federation.
Setup
To use the Contentful GraphQL API, you must configure your Supergraph to pull from the Contentful schema.
Here is an example configuration:
const gateway = new ApolloGateway({
buildService({ url }) {
return new (class extends RemoteGraphQLDataSource {
fetcher = makeFetchHappen.defaults({
headers: {
Authorization: `Bearer ${YOUR_TOKEN}`,
},
});
})({ url });
},
serviceList: [
{ name: "contentful", url: contentfulUrl },
...otherServices,
],
});
Now, when you start your Apollo Gateway server you should be able to access all Contentful queries through your Supergraph.
References
To resolve references from other subgraphs, you must add the Sys
type to the subgraphs from where you want to make references. This is only supported on Published
entities, and you will need access to both the locale you want and the ID of the entity in Contentful. For example, if you had a BlogPost
type from Contentful that you wanted to reference in your BlogPage
type, your types may look like this:
type Sys {
id: String!
locale: String
}
type BlogPage {
id: ID!
title: String
blogPost: BlogPost
author: Author
}
// You, 1 second ago + Uncommited changes
type BlogPost @key(fields: "sys { id locale }", resolvable: true) {
sys: Sys!
}
Then, your BlogPage
blogPost
resolver in your subgraph needs to return an object containing the key and the locale. Here is an example:
{
id: `1`,
title: `My English American Blog Page`,
author: {
name: `Bob`,
},
blogPost: { sys: { id: `blog-post-id`, locale: `en-US`} },
}
This will allow your gateway to talk to the Contentful Subgraph and look up the correct entry you are referencing.
Extend Types
You can extend Contentful Types following the Apollo specification. For example:
type Sys {
id: String!
locale: String
}
type BlogPost @key(fields: "sys { id locale }", resolvable: true) {
sys: Sys!
fieldFromSubgraph: String
}
Then, in your subgraph you can add a resolver to your resolver map that is responsible for returning that data to the gateway. Here is a very basic example:
BlogPost: {
fieldFromSubgraph() {
return `Some text from the other subgraph (not Contentful)`
},
}