33
loading...
This website collects cookies to deliver better user experience
/users/<id>
endpoint. You might hit it and get back a user object, complete with a name and the id of our chosen user’s best friend. If we want to show the logged-in user their best friend’ names in our UI, then one option is to make two requests to /users/<id>
; the first with the logged-in user’s id, and the second with her best friend’s id (which we only know from the response to the first call). This is slow (HTTP requests are probably the slowest part of your application) and it involves more code than we want to write. We want to write code to fetch some data we want, not code to fetch part of the data we want, and then once that’s come back to make another request which uses some of the first lots of data to fetch the rest.user
s have name
s and bestFriend
s. It even knows that bestFriend
s are in fact user
s and therefore it can retrieve a name
(or even a bestFriend
!) for the bestFriend
of a given user. When our UI changes, we update our query to ask for the relevant data, but the API remains unchanged.users
service, which contains all the code to retrieve that information, will get used more than, for example, our email service, which might send notifications to our users when it’s their best friend’s birthday. So we probably want more instances of our users
service running than of our email service, so that nobody gets any dropped requests for their best friend’s name, and we’re not paying for unneeded availability for our email service. But if the two are part of the same monolithic application (allowing one API to access them both), this seems to be impossible.graphql-tools
and apollo-link-http
. We'll also need node-fetch
for communicating between servers. To create our new GraphQL microservice, which we’ll call graphql-server
, we need to be able to do three things:graphql-tools
has all the tools we need for each of these things!import {
introspectSchema,
makeRemoteExecutableSchema,
mergeSchemas
} from "graphql-tools"
import { HttpLink } from "apollo-link-http"
import fetch from "node-fetch"
introspectSchema
, passing in instructions about how to find the remote schema. And guess what, Apollo have a tool for creating those instructions too.graphql-tools
docs, "Apollo Links are chainable 'units' that you can snap together to define how each GraphQL request is handled by your GraphQL client."HttpLink
is a specific type of Apollo Link which describes where to find a schema, like this:const schemaLink = new HttpLink({ uri: "https://your-api.com/graphql", fetch })
const schemaDefinition = await introspectSchema(schemaLink)
const remoteSchema = makeRemoteExectuableSchema({
schema: schemaDefinition,
link: schemaLink
})
remoteSchema
is now a fully-fledged GraphQL schema, ready to receive requests. We’ll need to repeat steps one and two for each remote schema (i.e. each of our microservices), and we’ll assume the resulting schemas are in an array called remoteSchemas
. All that remains is to merge them together.const mergedSchema = mergeSchemas({ schemas: remoteSchemas })
mergedSchema
is a single schema that contains all the individual schemas from steps one and two, meaning it can execute any query or mutation that any of the remote schemas could execute. And it will do so by delegating the query or mutation to the microservice whose schema originally defined it.mergedSchema
and expose it on an HTTP endpoint and you’re good to go.33