Apollo Server: An Introduction to the Leading GraphQL Server

Getting started with Apollo Server and Graph Manager to serve and manage your Data Graph

Image for post
Image for post

Apollo Server is a spec-compliant GraphQL server implementation written in JavaScript. It is today the industry standard GraphQL solution, and therefore the recommended option if you are considering a Data Graph solution for production apps.

This article focusses on two of the packages in the Apollo ecosystem: Apollo Server and Apollo Graph Manager. Apollo Server is an open source package used to build and run your GraphQL API, whereas Apollo Graph Manager is a dashboard hosted by Apollo you can use to manage, monitor and test your graphs. Graph Manager is an opt-in product that some may question the relevance of, being a centralised service in a world where open source software is becoming more prominent. But nonetheless, the service does offer some very useful insights into your server that this piece introduces.

Apollo Server and Graph Manager are the key tools used to set up and monitor your Data Graph, and are all that’s needed to get started serving a GraphQL API in production. We will document the setup process that will then pave the way for clients to make requests to your API, and for you to monitor activity with Graph Manager.

Another term used to describe a GraphQL API is a Data Graph. This article uses the term Data Graph as a general term for your GraphQL schema running with Apollo Server.

This article follows on from my previous introduction to GraphQL that is aimed at developers new to GraphQL itself. In that piece, the reference implementation of GraphQL (found on NPMJS at graphql) is used to discuss the core concepts and schema language of GraphQL, being a simpler and friendlier introduction than Apollo:

The GraphQL Foundation maintain reference implementations of GraphQL that acts as a good point of entry into GraphQL concepts, schema and demo applications.

If you wish to read through the above article first and then revisit this one, you will discover the shortfalls of the reference implementation and why the Apollo Server is much more capable for production ready apps.

Before jumping into setting up an Apollo Server and connecting it to Graph Manager, let’s cover some background about Apollo and why is it the leading GraphQL solution at the time of this writing.

There are a number of factors that make Apollo the go-to GraphQL solution for a JavaScript developer:

  • Apollo offer the most capable GraphQL implementation that can support both small and very large data graphs. The codebase adheres to the latest ECMA standards and is actively maintained.
  • The surrounding ecosystem of tools in the Apollo suite, that also include Apollo Clients for iOS and React and Apollo Link in addition to Server and Graph Manager. The Apollo clients cover the most relevant client-side languages today, whereas Apollo Link and Graph Manager provide much more robust tooling than other implementations, for customising GraphQL operations and providing analytics metric solutions for enterprise clients or large teams respectively.

This article does not focus on Apollo Link or the Apollo clients. Although it is beneficial for the reader to be familiar with these tools, as they’ll undoubtedly become useful after your server is running, they are not needed to build or establish your Data Graph.

  • The community adoption and community driven tools available that greatly help in modularising your schema and resolvers, and organisation of your codebase in general. Two major packages to be aware of are graphql-tools and graphql-toolkit.
  • Apollo Server runs on a Node JS runtime, either on its own or as an Express or Connect server setup. It is very simple to integrate Apollo Server with popular server frameworks, and can even work alongside existing REST APIs on the same server process (a GraphQL service only needs one endpoint to handle all requests to your Graph that is commonly at the /graphql endpoint). We’ll be using apollo-server-express further down when setting up our own server.

It is worth emphasising that using Apollo Server does not lock you into using the Apollo Clients; Apollo Server can serve any GraphQL client. This is self-evident given the universally accepted GraphQL schema syntax and conventional HTTP endpoints of a GraphQL service.

With all this being said, let’s now set up an Apollo Server and run through some key installation that’ll make developing your Data Graph a more seamless experience.

Setting up Apollo Server

The official Apollo Getting Started doc cover how to get started with the apollo-server package, and not for integrating Apollo Server with Express or another framework. What we’ll do here is cover the setup instructions for apollo-server-express instead; as this will most likely be the reader’s preferred choice.

At the time of writing, apollo-server-express has ~954,000 weekly downloads whereas the standalone apollo-server package has ~366,000. Developers are clearly opting to use Apollo Server in conjunction with a framework.

Starting with a bare directory, run the following to initiate a new project, that this article will simply call apollo-server:

# create project directory and init new `package.json`mkdir apollo-server
cd apollo-server && yarn init

All standard practice here. Next install two required dependencies that the project will be needing — apollo-server-express and dotenv:

yarn add apollo-server-express dotenv

Apollo Server will need confidential API keys further down, along with other environment variables; dotenv gives your project the ability to fetch environment variables from a .env file, storing them in a process.env object. This .env file should be in your .gitignore file.

If you use the Node .gitignore file supplied by GitHub, .env will already be defined in there. Go ahead and copy that file into your project directory.

Now is a good time to initialise git within the project directory, and link it with a remote repository if you have one set up:

# initiate gitgit init
git remote add origin <url>
git commit -m 'initial commit'
git push origin master

Although we tend to take git for granted these days, it is imperative that GraphQL schema is managed under source control, to have the ability to rollback on breaking changes, experiment with different versions without breaking the master branch, and just to document the evolution of your schema.

In fact, what we’ll discover further down is that Apollo Graph Manager has its own mechanism of tracking schema history, as well as “variants” of schema that you can push to the service, adding more significance to the practice of source controlling schema.

Before moving onto the CLI and other environment tooling, let’s set up a bare bones Apollo Server with a hello query that simply resolves “Hello World!”. This gives us something tangible to work with for future setup. Take the following Gist that spins up the server on port 4000:

Notice that dotenv is included in the first line, ready to support environment variables from .env. If this is your first look at an Apollo Server, take note of the following:

  • The gql string literal is heavily used to wrap GraphQL Schema, both on the server side and client side of a GraphQL implementation. This gql tag transforms schema syntax into “GraphQL AST”, a formatted structure of the query that the underlying Javascript VM understands and processes.
  • The Apollo Server is initialised as a new ApolloServer object, that supports a range of configuration options. In the example above we’re simply providing the schema and resolver objects, with everything else relying on default values.
  • The applyMiddleware method attaches Express middleware we can configure within the ApolloServer initialisation. We have not done so in the code above, but as an example, we could have set cors: true as an additional property, and applyMiddleware would have then apply the cors middleware to the app.

applyMiddleware is a shorthand method of app.use(). You can still use app.use() to attach middleware — it is still necessary if you wish to expand your middleware and custom middleware functions beyond what ApolloServer can configure.

Open your terminal (or press CTRL+` in VS Code) and run your server with nodemon. Your server will now be live and serving requests from http://localhost:4000/graphql. Copy this address in your browser to reveal the GraphQL Playground — a lightweight IDE that runs in development mode for you to test your queries.

Image for post
Image for post
The GraphQL Playground GUI running in the browser at your service URL

Run the following hello query and examine the right side response to verify everything is working as expected:

# running the `hello` 
{
hello
}
> {
"data": {
"hello": "Hello World!"
}
}

Apollo Graph Manager has a similar tool called Graph Query Builder, or Apollo Studio depending on what documentation you’re reading (the service is quite new and rapidly evolving), that can also test production servers. We’ll check that out further down.

With the means of developing and testing your schema now set up, we’ll cover a couple more essential tools before moving on to Graph Manager.

Be sure to install the Apollo GraphQL Plugin for VS Code, that adds a range of essential tools for developing your Data Graph including the standard syntax highlighting among more advanced features.

You will also notice that the plugin requires an apollo.config.js file in your project’s root directory, and more specifically a name field to represent your service. This file plays a part in communicating with Graph Manager too.

Introduce the file here with your service name, as well as the default endpoint of your service:

// apollo.config.jsmodule.exports = {
service: {
name: 'apollo-server',
endpoint: {
url: 'http://localhost:4000/graphql',
skipSSLValidation: true // optional, disables SSL validation check
} }
};

The skipSSLValidation option may be useful for you if you are running the service behind a reverse proxy, or testing it locally on your machine without SSL support.

The apollo.config.js file is used both server side and client side where you are using Apollo React or Apollo iOS. There is a dedicated document detailing every config option, but for the server side options only, visit the Server Projects section at the bottom of the document (there are a lot less server side configs than client side!).

Another essential tool is the Apollo CLI, that we’ll use to push schema to Graph Manager in the next section. Either install the package globally or as a dev dependency (perhaps preferable if you’re working as a team).

# install globally 
yarn global add apollo
# and / or as a dev dependency
yarn add -D apollo

I tend to install globally by default as all my local projects can utilise the tool without more installations, but the developer dependency route definitely makes sense if you’re distributing your project to a large team.

Setting up Apollo Graph Manager

Let’s now move onto the second part of this setup journey with Graph Manager. There is a useful Overview video hosted on the official documentation homepage for the service that is worth watching first.

The landing page of the service is hosted here — a minimally designed landing page presenting the sign in form:

Image for post
Image for post
The Graph Manager Landing / Sign In Page

From my impressions, Apollo Graph Manager is still in its early stages of development. It is clear by the generic dashboard design and lack of customisation in terms of displaying data that this is due to features not being ready, rather than a deliberate choice to keep clean interfaces. Be patient if you like using the service, and expect the UI and offering to evolve quickly.

To reiterate what was stated in the introduction, Apollo Graph Manager is not a compulsory service that must be used alongside Apollo Server — instead it is used to compliment the Server component by offering you a multitude of tools for management and analytics. There is a paywall on features designed for large teams and enterprises (see pricing here), that include tools like real time performance monitoring with detailed metrics, and real time schema validation.

For the purpose of studying the Apollo Suite, GraphQL schema and to gain insight on how your server performs, I recommend at least experimenting with (free) Graph Manager to gain further insights on how GraphQL works, and to at least be exposed to the latest utility efforts from Apollo.

We’ll stay focused on the free features in this piece. To decide whether Graph Manager is worthwhile to integrate for you, here are the main things we can do in Graph Manager:

  • Tracking schema changes, similar to a git commit history, that outlines the changes you make to your schema over time. Pushing schema updates requires the Apollo CLI we installed above that we will look at further down.
  • The ability to publish different variations of your schema, for example, a sandbox, staging or production schema (you could also publish local development schema for reference purposes). Graph Manager terms this feature “Schema Variants” that we’ll look into setting up next.
  • An Explorer and History GUI that gives you high level metrics such as how many queries your particular schema variant has served, with the ability to even drill down to the format of the query. Query variables (that may be confidential user data, passwords, etc) are omitted by default when queries are sent to Graph Manager. Surprisingly, this was not the case with previous versions.
  • The ability to categorise schema per project, and host projects in organisations, as well as other standard organisation management.
  • The ability to test production schema via the Graph Query Builder tool, currently in pre-release at the time of this writing — things may change before final release.

Register a new account now to continue exploring the dashboard. Graphs are hosted in an organisation, so make sure to create at least one.

In order to link a project to Apollo Graph Manager, a new “Graph” needs to be created on the Dashboard. From here, API Keys can be generated for that Graph in its Settings section. We copy this API key into apollo.config.js and our job is done — Graph Manager does the rest to populate the dashboard (it fetches the latest usage data from your public Graph URL).

Let’s create a Graph now and publish a schema to it from your development project (if you followed the previous setup, it should have the hello query defined). Once your organisation is created:

  • Click New Graph and give it a name before creating it. For this walkthrough we’ll call it apollo-server. Important: This name needs to be the same name you declared earlier in apollo.config.js. Graph Manager requires Graph names to be globally unique, so if following along with this article, make sure you update your apollo.config.js with your chosen name now.
  • Click the Graph name on the left side to access its various menus. Go to Settings (under the Graph Settings menu) on the left side, and copy your API Key Token under the API Keys section. Add this token to your .env as APOLLO_KEY, along with an NODE_ENV environment variable:
// .envNODE_ENV=development
APOLLO_KEY=<your_token>

Note that this APOLLO_KEY is different from the API Keys you can also generate from your Personal Settings section of the dashboard.

  • Back in index.js, Add your APOLLO_KEY to the engine.apiKey property when initialising the service with ApolloServer:
// index.js...// Initiate Apollo Server
const server = new ApolloServer({
typeDefs,
resolvers,
engine: {
apiKey: process.env.ENGINE_API_KEY,
graphVariant: process.env.NODE_ENV,
},
cors: true,
});
...

Notice also that an engine.graphVariant property is also defined using NODE_ENV, which will be development on your local machine, and production on your server. This will allow you to publish usage data to Graph Manager on a per-variant basis, with the names somewhat unsurprisingly being development and production.

Notice that cors is also being set to true here, so applyMiddleware can go ahead and add the cors middleware automatically.

  • Publish your schemas. It is likely that your development and production schemas will be the same at this point, so run two commands using the Apollo CLI to send them to Graph Manager:
apollo service:push --variant=development
apollo service:push --variant=production

If publishing multiple variants from the same local machine, it may be useful to branch out your project to facilitate the different versions.

Omitting the --variant flag will publish a schema inside a current variant by default, but using standard variant names from the off makes more sense; establish that convention early.

You can delete variants in Graph Manager by clicking the variant and deleting it under Settings.

With your environment now set up, now is a good time to explore the dashboard and follow the official documentation with the features that interest you, with schema management being the main benefit of the free version.

It is fun to see Graph Manager being populated as queries arrive to your production service. In order to run queries yourself, open up Apollo Studio , a similar tool to GraphQL Playground used in the development environment. Here is what Apollo Studio looks like, sporting a dark theme I am very fond of:

Image for post
Image for post
Apollo Studio GUI, found at engine.apollographql.com/studio

I have omitted my API URL and service name for security purposes. The main takeaway here is that you can toggle between Graphs and API Endpoints and test queries on the fly. As you can see, the software automatically picks up on your schema, having our hello query displayed by default.

Apollo Studio is quite hard to find. To open it up, open your Graph Settings -> Open the right-side menu in your Manage Variants section -> click Open in Graph Query Builder:

Image for post
Image for post
How to find Apollo Studio Link within Graph Settings

Okay, your environment is set up now! Let’s briefly cover some important points about hosting your production Data Graph before closing off this piece.

Hosting a Production Apollo Server

This section aims to clarify some production pointers and limitations so you do not run into them yourself.

The Apollo Server source control and server setup is straight forward if you are accustomed to configuring REST APIs or Express servers. Here is a typical setup:

  • Running your Apollo Express server with a process manager like PM2, ensuring uptime and automatic restarting.
  • Having GitHub Webhooks or your CI tool of choice to automatically pull the latest commit of your project, run yarn, and restart that PM2 process.
  • Have an Nginx server config handle encrypted requests to your service, and routing those requests via a reverse proxy to your Apollo Express server exposed on a port at localhost.
  • Close all ports via your firewall, only allowing that encrypted traffic access to your /graphql endpoint.
  • If you adopt containerisation like Docker and / or scaling solutions like Kubernetes, then your Apollo Server can be configured as an image and replicated throughout your cluster.

There is one consideration when pushing your latest schema to Graph Manager though — it cannot be done in a production environment.

You cannot push schemas to Graph Manager from a production environment, therefore it has to be done with CI or in a local environment instead. Try using apollo service:push on your production server to witness it return an error.

If you were thinking something along the lines of “I’m going to integrate the apollo service:push command as an extension of my GitHub Webhooks setup to automate it within my existing auto deployment script”, that sounds perfectly plausible and logical, but will unfortunately not work.

There is some valid logic in not pushing schema updates from a machine intended to host, not to develop / change code, so the limitation does make sense to prevent management issues in the pipeline. An intermediary CI server or deployment script / tool would be the ideal place to push schema updates to Graph Manager.

In Summary

This article has acted as an introductory to Apollo Server and the accompanying Apollo Graph Manager tools, along with mentioning of other tools in the GraphQL and Javascript ecosystems for the reader to explore. It has aimed to be a natural progression from my previous article: GraphQL in JavaScript: An Introduction.

Where the first article introduced GraphQL and its core concepts at a high level, this article introduced the industry standard tools for implementing a Data Graph Service for your production apps. It should be apparent to the reader now that Apollo is aiming to offer a superior solution to traditional RETful APIs, and a more feature rich solution than other GraphQL implementations, including their SaaS efforts in Graph Manager.

We covered the benefits of Apollo over other implementations, such as the JavaScript reference implementation, and what Apollo Server and Graph Manager offer from a development perspective. We then covered the setup of both products with tips and thoughts along the way. The reader should now feel comfortable navigating the official documentation and discovering the other features Apollo have to offer, such as the tools aimed for larger projects with Apollo Federation.

The client side of Apollo (with Apollo iOS or Apollo React, or others — Apollo Server is compliant with any GraphQL client) will be the talking point of a future article, where there will also be a bigger focus on schema syntax and delivering queries to the clients themselves. In the meantime, enjoy discovering and building your services with the rapidly growing user base of GraphQL!

Programmer and Author. Director @ JKRBInvestments.com. Creator of ChineseGrammarReview.app for iOS.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store