Can MongoDB Atlas GraphQL API be used with Apollo Federation (as a subgraph under an Apollo supergraph)?

If we have a MongoDB database and app service for it, utilizing the Atlas GraphQL API, it autogenerates the GraphQL schema itself and you cannot modify as far as I can tell.

I want to know if I can use this as a subgraph in Apollo Federation. The reason I am unsure if it will work, is Apollo Federation appears to require metadata & directives to specify to the supergraph certain things (ie. the @keys directive on a type to say which fields are the Ids defined in both subgraphs). Because of stuff like this, and not seeing a way to add this to the GraphQL schema within the app service / Atlas GraphQL API, I don’t believe it would work.

But, in this article Building a Modern App Stack with Apollo GraphQL and MongoDB Atlas | MongoDB Blog I see that it is talking about Apollo supergraphs, and mentions the Atlas GraphQL API as 1 of 4 options, so it seems to imply it should be possible.

I realize that I could create my own service to handle GraphQL requests with Apollo Server or something similar, and hook it up to MongoDB as the datasource with something like Mongoose and therefore use it with Apollo Federation, but I am wondering if it is possible to use the Atlas GraphQL API as a subgraph for Apollo Federation.

2 Likes

That’s a really good question because I also just finished viewing the youtube video you mentioned, and I was very disappointed : At the beginning of the video, she talked about how it is really quick to create its own GraphQL API based on its MongoDB collections, but then, the guy who presents the federation recreates all those APIs from scratch.
So where is AppService GraphQL usefull here ???

1 Like

Hello,

  1. Any update on this? Have you tried to implement it?

  2. As alternative i was thinking to use the function trigger from atlas service to control the input data or requesting external API (to retrieve extra information for example) before updating the database, but I dont know how flexible it is and if it will be easy to maintain. Any thought about it?

The only way to enable an AppServices GraphQL API is to be able to add some custom directives to the generated schema (@keys, @shareable, @provides …etc) but it is not possible for the moment.

So right now the best way and more flexible would be to create my own graphql subgraph as on the video Building a Modern App Stack with Apollo GraphQL and MongoDB Atlas | MongoDB Blog

Also I would like to know how can i control the input data with AppService GraphQL, for example to check that a description field is smaller than 300 characters.

Should I create a trigger function (database insert/update type of trigger) on every graphql query to parse the input data and make sure that it is correct?

That’s what I did finally. I created my own federation with NestJS and Apollo server. I abandoned the idea of using Appservice to create my graphql apis and use them inside a federation. It’s just a shame because the GQL schema generation is really awesome and really helpful to have a complete CRUD graphQL API on your data.

I think i will still use the appService and use Apollo Server as a graphql proxy that will do graphql query to the AppService and check the input data. I dont know if it is a good idea but AppService has nice features that can be helpful later (triggers/eventBridge on database update - authentication…) and add a layer of abstraction on the database.

This is the tech doc I wrote up a couple weeks ago for connecting MongoDB Atlas GraphQL API to an Apollo GraphQL service, is this what you’re looking for?

To connect MongoDB Atlas GraphQL with Apollo GraphQL, follow these steps:

  1. Create a MongoDB Atlas GraphQL service. This can be done in the Atlas console by selecting your cluster, navigating to the “GraphQL” tab, and clicking “Create Service”. Follow the prompts to create a new service.

  2. Once the service is created, note the GraphQL Endpoint URL and the Access Key. These will be used to connect to the service from Apollo.

  3. In your Apollo server, install the apollo-server and graphql packages. These can be installed using npm or yarn.

  4. Create a new instance of the ApolloServer class and pass in a configuration object that specifies the schema and resolvers for your GraphQL API. For example:

const { ApolloServer, gql } = require('apollo-server');

const typeDefs = gql`
  type Query {
    hello: String
  }
`;

const resolvers = {
  Query: {
    hello: () => 'Hello world!'
  }
};

const server = new ApolloServer({
  typeDefs,
  resolvers
});

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});
  1. Install the graphql-request package, which will be used to make requests to your MongoDB Atlas GraphQL service. This can be installed using npm or yarn.

  2. In your Apollo server, create a new instance of the GraphQLClient class from graphql-request. Use this instance to make requests to your MongoDB Atlas GraphQL service. For example:

const { GraphQLClient } = require('graphql-request');

const client = new GraphQLClient('https://your-atlas-graphql-endpoint', {
  headers: {
    Authorization: `Bearer ${your-access-key}`
  }
});

client.request(`{
  hello
}`).then(data => console.log(data));

Replace your-atlas-graphql-endpoint with the actual GraphQL Endpoint URL of your MongoDB Atlas service, and your-access-key with the actual Access Key for the service.

  1. You can now use the client instance to make requests to your MongoDB Atlas GraphQL service from your Apollo server. For example, you can modify the previous code snippet to use the client instance to make the hello query:
const { ApolloServer, gql } = require('apollo-server');
const { GraphQLClient } = require('graphql-request');

const typeDefs = gql`
  type Query {
    hello: String
  }
`;

const resolvers = {
  Query: {
    hello: async (_, args, context) => {
      const client = context.client;
      const data = await client.request(`{
        hello
      }`);
      return data.hello;
    }
  }
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: ({ req }) => ({
    client: new GraphQLClient('https://your-atlas-graphql-endpoint', {
      headers: {
        Authorization: `Bearer ${your-access-key}`
      }
    })
  })
});

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});

This code creates a new instance of the GraphQLClient class in the context function of the Apollo server. This instance is then passed to the resolvers as part of the context object, and used to make requests to the MongoDB Atlas GraphQL service.

1 Like

Ok, but here your are not using federation of graphQL APIs. You are just “resolving” to an Atlas GraphQL service from your apollo api.