GrAMPS is an easy way to set up a GraphQL gateway (server) using community-provided data sources. In the next 5 minutes, let’s set up a working GraphQL gateway, then pull in live data using a GrAMPS data source.
NOTE: This example uses yarn
. npm
alternatives are shown in comments.
# Make a directory and move into it.mkdir my-gateway && cd $_# Initialize a package.jsonyarn init -y# npm init -y
Because we want to use the modern features of Node, let’s create a minimal Babel configuration and add a build script.
yarn add --dev @babel/core @babel/cli @babel/preset-env# npm install --save-dev @babel/core @babel/cli @babel/preset-env
.babelrc
In the project root, add a new file called .babelrc
with the following configuration:
{"presets": [["@babel/preset-env",{"targets": {"node": "current"}}]]}
Thanks to the smarts under the hood of @babel/preset-env
, we don’t have to do much.
Once we have a server, we’ll need to run our code through Babel to avoid any compatibility issues. To do that, let’s add a build script to our package.json
:
{"name": "my-gateway","version": "1.0.0",- "main": "index.js",+ "main": "dist/index.js","license": "MIT",+ "scripts": {+ "build": "babel index.js -d dist"+ },"devDependencies": {"@babel/cli": "^7.6.4","@babel/core": "^7.6.4","@babel/preset-env": "^7.6.3"}}
NOTE: We also changed the
main
entry so that the default start functionality from Node will point to the built server.
Now that we’ve got a project to work in, let’s set up a simple Express server.
# Install server dependencies.yarn add express get-port# npm install --save express get-port
Create a new file called index.js
in the project root, then add the following:
import Express from 'express';import getPort from 'get-port';async function startServer() {const PORT = await getPort(8080);const app = Express();app.get('/', (_, res) => res.send('Hello world!'));app.listen(PORT, () => {console.log(`=> server running at http://localhost:${PORT}/`);});}startServer();
This file creates an Express app, sets up a “Hello world!” endpoint, and starts the app listening on port 8080 (or a random port if 8080 is already in use).
To verify that the server works, build and then start it:
yarn build# npm run build# Start the built servernode dist
Assuming port 8080 isn’t in use on your machine, opening http://localhost:8080/ should result in a “Hello world!” message.
Now that we have a working server, we can set up GrAMPS to get our gateway running.
yarn add @gramps/gramps apollo-server-express graphql# npm install --save @gramps/gramps apollo-server-express graphql
import Express from 'express';import getPort from 'get-port';+ import { ApolloServer } from 'apollo-server-express';+ import gramps from '@gramps/gramps';async function startServer() {const PORT = await getPort(8080);+ const GraphQLOptions = await gramps();+ const server = new ApolloServer(GraphQLOptions);const app = Express();+ server.applyMiddleware({ app });- app.get('/', (_, res) => res.send('Hello world!'));app.listen(PORT, () => {console.log(`=> server running at http://localhost:${PORT}/`);});}startServer();
Let’s make sure everything is working by starting the server and running a test query.
yarn build# npm run buildnode dist
Open http://localhost:8080/graphql and run the following query:
{grampsVersion}
The result should look something like this:
{"data": {"grampsVersion": "4.0.0"}}
NOTE: By default, GrAMPS exposes a single query —
grampsVersion
— which returns the current package version of@gramps/gramps
.
Now that the gateway is running, let’s hook it up to some data by installing the xkcd GrAMPS data source.
yarn add @gramps/data-source-xkcd graphql-tools# npm install --save @gramps/data-source-xkcd graphql-tools
NOTE: GrAMPS data sources have a
peerDependency
ofgraphql-tools
. This avoids a conflict where multiple data sources could introduce multiple versions ofgraphql-tools
as subdependencies.
Adding data sources to a GrAMPS gateway requires just two lines of code:
import Express from 'express';import getPort from 'get-port';import { ApolloServer } from 'apollo-server-express';import gramps from '@gramps/gramps';+ import XKCD from '@gramps/data-source-xkcd';async function startServer() {const PORT = await getPort(8080);- const GraphQLOptions = await gramps();+ const GraphQLOptions = await gramps({+ dataSources: [XKCD]+ });const server = new ApolloServer(GraphQLOptions);const app = Express();server.applyMiddleware({ app });app.get('/', (_, res) => res.send('Hello world!'));app.listen(PORT, () => {console.log(`=> server running at http://localhost:${PORT}/`);});}startServer();
To verify that everything is working, run the following:
yarn build# npm run buildnode dist
Open http://localhost:8080/graphql and run the following query:
{getComicById(id: 123) {titlelink}}
You should see the following output:
{"data": {"getComicById": {"title": "Centrifugal Force","link": "https://xkcd.com/123/"}}}
Bam! We just added live data from a third party in two lines of code!
In order to give ourselves the ability to develop more easily — for example, using mock data, or running our gateway with a local data source we’re building — we’ll need to add the GrAMPS CLI.
yarn add --dev @gramps/cli# npm install --save-dev @gramps/cli
Let’s add a dev
script that will run the GrAMPS CLI’s dev
command and tell it to use our gateway.
For convenience, let’s also add a predev
script to rebuild the gateway every time we run the dev
script.
{"name": "my-gateway","version": "1.0.0","main": "index.js","license": "MIT","scripts": {+ "predev": "yarn build",+ "dev": "gramps dev --gateway dist","build": "babel index.js -d dist"},"devDependencies": {"@babel/cli": "^7.6.4","@babel/core": "^7.6.4","@babel/preset-env": "^7.6.3","@gramps/cli": "^1.5.3"},"dependencies": {"@gramps/data-source-xkcd": "^2.0.0","@gramps/gramps": "^4.0.1","apollo-server-express": "^2.9.6","express": "^4.17.1","get-port": "^5.0.0","graphql": "^14.5.8","graphql-tools": "^4.0.5"}}
NOTE: If you’re using
npm
, make sure to update thepredev
command to usenpm run build
instead.
Test that the script worked by running the following:
yarn dev# npm run dev
Open http://localhost:8080/graphiql and run a test query. This should be exactly the same as our previous test of the gateway.
Next, let’s use the CLI to run our gateway with mock data:
yarn dev --mock# npm run dev -- --mock
Open http://localhost:8080/graphiql and run the test query again:
{getComicById(id: 123) {titlelink}}
This time, the response should be placeholder text that looks something like this:
{"data": {"getComicById": {"title": "Quidem illo","link": "http://Sylvester.biz/"}}}