Skip to content

Integrating Mercurius with Apollo Studio

Leveraging the Apollo Toolbelt with Mercurius GraphQL Server

In this article, we outline how you can use the mercurius-apollo-registry and mercurius-apollo-tracing plugins to switch from apollo-server to mercurius as your GraphQL API server.

Apollo Studio-compatible GraphQL Servers

Apollo Studio is one of the leading developer tools for documenting, monitoring and measuring the performance of GraphQL APIs. When it comes to integrating it with a Node.js GraphQL backend, the most obvious way to do it is via apollo-server. The protocols for tracing and schema reporting are available for anyone to implement, but very few GraphQL server implementations do.

There are several implementations of metrics reporting for languages other than javascript, but for Node.js there is only one alternative server framework with an existing implementation of tracing and schema reporting.

apollo-server-core and its adapter packages

apollo-server-core is the backbone for all the server packages published by Apollo. It contains features shared by all of the individual packages: Express, Koa, Hapi, Lambda, even Fastify. These adapters are tiny wrappers connecting the GraphQL response handler into the HTTP handler properly for each framework. Under the hood, it’s always apollo-server-core, which has both tracing and schema reporting built in. You don’t need to install any additional packages to use it with Apollo Studio.

mercurius

At Nearform we use mercurius , a GraphQL server implementation built as a Fastify plugin. Mercurius does not run on apollo-server-core; it uses its own implementation based on the canonical graphql package. We wanted to leverage the Apollo Studio as well, so we wrote two new libraries for mercurius. These are essentially Fastify plugins that integrate mercurius with Apollo Studio. They are not included by default — Fastify is governed by the minimal core principle, so these integrations are separate npm modules. They do not pollute node_modules for those who do not need to integrate with Apollo Studio.

mercurius-apollo-registry

mercurius-apollo-registry plugin enables schema reporting. This is useful as your API develops over time. Apollo Studio generates useful changelogs for any change to the API’s shape and tracks versions for you. We have written about using this plugin with a Schema registry .

Setup

First, install with npm install mercurius-apollo-registry .

Then you can register the plugin in your Fastify app:

JavaScript
fastifyApp.register(mercuriusApolloRegistry, {
  Schema,
  // replace 'your:Api:Key' with the api key from apollo studio
  apiKey: 'your:Api:Key',
})

Usage

For a simple schema like basicSchema (left of image below), if we add a new root query, we can see the changelog in Apollo Studio picks up on the change once we run our server:

mercurius-apollo-tracing

mercurius-apollo-tracing plugin is used to collect runtime performance metrics as well as errors from your GraphQL resolvers. These get sent to the Apollo Studio’s ingress endpoint. If you have on-premise Apollo Studio or any other server compatible with the apollo tracing format , you can send your reports there just by specifying a different URL to the plugin options.

Apollo studio has a UI to explore the data collected. You can see timings for every resolver and all errors thrown in your resolvers.

Tracing protocol

Apollo tracing is defined as GraphQL extension for performance tracing. It contains the definition for GraphQL execution trace format . This is a sample trace for a GraphQL query like this one:

JavaScript
{
 "endTime": {
   "seconds": "1633005166",
   "nanos": 150000000
 },
 "startTime": {
   "seconds": "1633005166",
   "nanos": 148000000
 },
 "http": {
   "method": "POST"
 },
 "durationNs": "2402411",
 "root": {
   "child": [
     {
       "responseName": "add",
       "type": "Int",
       "startTime": "982803",
       "endTime": "1990096",
       "parentType": "Query"
     },
     {
       "responseName": "word",
       "type": "String",
       "startTime": "1156015",
       "endTime": "1496289",
       "parentType": "Query"
     },
     {
       "responseName": "post",
       "type": "Post!",
       "startTime": "1641821",
       "endTime": "1993796",
       "parentType": "Query",
       "child": [
         {
           "responseName": "title",
           "type": "String",
           "startTime": "2699346",
           "endTime": "2746007",
           "parentType": "Post"
         },
         {
           "responseName": "body",
           "type": "String",
           "startTime": "2794377",
           "endTime": "2799787",
           "parentType": "Post"
         }
       ]
     }
   ]
 }
}

We can see startTime and endTime are recorded for each GraphQL resolver. Thanks to process.hrtime() , we get nanosecond precision here allowing us to measure even the smallest performance gains. Each trace like this gets serialised into a protobuf using apollo-reporting-protobuf and sent to the ingress endpoint of Apollo Studio API.

Setup

Similar to the registry plugin, install the plugin from NPM with npm install mercurius-apollo-tracing . Next, you need to copy your Graph ref from the graph detail page in Apollo Studio . It will be in the format “yourGraphName@variant”. Graph ref is a unique identifier for a schema deployment inside Apollo Studio. Last, register the plugin in the following way in your existing Fastify app:

JavaScript
fastifyApp.register(mercuriusTracing, {
 apiKey: 'your:Api:Key', // replace 'your:Api:Key' with the one from apollo studio
 graphRef: 'yourGraph@ref' // replace 'yourGraph@ref'' as well
})
Localhost tracing

You can even trace your API running on your development machine before you deploy your API to a live environment. Simply point it to your localhost URL:

Make sure you have CORS headers enabled on the API server because Apollo Studio makes requests directly from the browser, so your GraphQL API must respond with a CORS header.

Performance penalty

All logging/tracing inevitably slows down observed system performance, and mercurius-apollo-tracing plugin is no exception. For exact numbers we’ve measured, see the readme on GitHub , but we’ve made sure the slowdown is less than with the apollo-server-fastify package. Enabling tracing there slows the resolver's execution even more.

Wrapping up

With these two plugins, you can get the same level of granular reporting capability and overall developer experience in Apollo studio as you get with apollo-server. This makes the decision easier if you are on apollo-server and are considering switching to mercurius as your GraphQL api server.

Insight, imagination and expertly engineered solutions to accelerate and sustain progress.

Contact