Simple and to the point stitching remote schema into local schema with Apollo Server
Tags: javascript, graphql, apollo, stitching
Published: 2019-05-23 12:28:37

---
title: Simple and to the point stitching remote schema into local schema with Apollo Server
published: true
description: We create a utility function to merge a remote squema with a local one. You can use it right away or dive into learning how it works step by step.
tags: javascript, graphql, apollo, stitching
cover_image: https://i.imgur.com/jh15Qk1.png
---


*Cover photo by [Two Paddles Axe and Leatherwork](https://unsplash.com/photos/9wNcZprwco8) on Unsplash*


Scenario: You have your first schema running on your Apollo server but a new GraphQL API shows up and you need to work with it in your client right away without too much orquestation.

This tutorial will try to get you from point A to point B as fast as possible. We will make a small API to solve our problem and for future reuse. You can use it right away but we will be explaining each piece step by step to get the inner workings.

A note:
Stitching local with remote schemas, I think, works perfectly in the situation where you are **starting to stitch**. Why? Because you have your first schema already up and running. If a GraphQL service shows up just append this new remote schema on top to start consuming it.

I'm telling you this because there is another way of working this out AFAIK but we would need to start another microservice to serve as a proxy to both of our APIs (local and remote schemas will be both remote now). I think this could work well when you have too many services but for a start let's just use our current server and enhance it with a new remote schema on top of it. It's faster, it's one less service to run, it works.


Right now supposedly we have this setup for our server.

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

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

We are going to replace previous code with this module.

```javascript
const { ApolloServer, makeExecutableSchema } = require('apollo-server')
const { HttpLink } = require('apollo-link-http')
const {
  introspectSchema,
  makeRemoteExecutableSchema,
  mergeSchemas,
} = require('graphql-tools')
const fetch = require('node-fetch')

async function startServer({
  localSchema: { resolvers, typeDefs },
  remoteSchema: { uri },
}) {
  const remoteHttpLink = new HttpLink({
    uri,
    fetch,
  })

  const remoteSchemaInstrospection = await introspectSchema(remoteHttpLink)

  const remoteSchemaExecutable = makeRemoteExecutableSchema({
    schema: remoteSchemaInstrospection,
    link: remoteHttpLink,
  })

  const localSchema = makeExecutableSchema({
    typeDefs,
    resolvers,
  })

  const mergedSchemas = mergeSchemas({
    schemas: [localSchema, remoteSchemaExecutable],
  })

  const server = new ApolloServer({ schema: mergedSchemas })

  return await server.listen()
}

module.exports = startServer
```


First we are going to make a request to our external GraphQL API. We pass to the config object our `uri` and a reference to the `fetch` library.

```javascript
  const remoteHttpLink = new HttpLink({
    uri,
    fetch,
  })
```

We use the `instrospectionSchema` function to retrive the schema from our remote GraphQL service. Only argument is our previously defined `HttpLink` instance.

```javascript
  const remoteSchemaInstrospection = await introspectSchema(remoteHttpLink)
```

We got our schema after introspection but now we are still missing making it executable. So it's a two step process. Being executable will enables us to later on merge it with our local one.

```javascript
  const remoteSchemaExecutable = makeRemoteExecutableSchema({
    schema: remoteSchemaInstrospection,
    link: remoteHttpLink,
  })
```

Next we create our local schema using `makeExecutableSchema` passing a config object as argument with our `typeDefs` and `resolvers` just like the typical server config object we saw at the beginning.

```javascript
const localSchema = makeExecutableSchema({
  typeDefs,
  resolvers,
})
```

Merge both schemas with `mergeSchemas`

```javascript
const mergedSchemas = mergeSchemas({
  schemas: [localSchema, remoteSchemaExecutable],
})
```

Pass it to our server in its config object and start it invoking `listen` as usual.

```javascript
const server = new ApolloServer({ schema: mergedSchemas })

return await server.listen()
```

We are done with the module breakdown 🙌. Now let's use it!

`startServer` has as argument one config object that has two properties:
- `localSchema` Object with two keys. `resolvers` and `typeDefs`.
- `remoteSchema` Object with one key.`uri`: string of our external GraphQL API.

```javascript
startServer({
  localSchema: {
    resolvers,
    typeDefs,
  },
  remoteSchema: {
    uri: 'https://01uhb.sse.codesandbox.io/',
  },
}).then(({ url }) => {
  console.log(`🚀  => Server ready at ${url}`)
})
```

And that's it. Now our current server has both of our schemas available.

Play with it yourself. Here's a codesandbox with the GraphQL server and our module in action. We have two queries. `hello` is local and the `goodbye` query is being merge.

{% codesandbox apollo-server-pu0gu %}

You can grab the external Graphql service here: <https://codesandbox.io/s/apollo-server-01uhb>

This is just the beginning. You have a lot to tweak and learn about stitching from here.

What if some types repeat between schemas?
What if I need to use the result type of one query in another one as an argument?

New challenges bring new ways to extend and work with combined schemas. 
Hope this tut is a good first step into your stitching journey!