DEV Community

peerhenry
peerhenry

Posted on • Edited on

Putting GraphQL Playground in front of AppSync

Prerequisite knowledge: Node, NPM and AWS AppSync

AWS AppSync is a service for hosting a GraphQL API with cool features like being able to generate backend resources based on a schema. We can inspect and debug that API from the queries tab in the AppSync console. But there's another tool called GraphQL Playground that has a lot more features like tabs, history, prettification, complete schema inspection and custom settings. It's also nice not having to login to AWS in order to debug or play around with our GraphQL API. So let's take a look at how we can hook up GraphQL Playground to AppSync.

Step 1: Install the necessary packages

After setting up your project with npm, we are going to install the following dependencies:

npm i -S express @workpop/graphql-proxy graphql-playground-middleware-express babel-runtime

We are going to run a node server using express. Then we need a way to proxy our GraphQL API so that our queries and mutations get forwarded to AppSync. That's where @workpop/graphql-proxy comes in. This package is built for schema stitching, which is useful if you need to combine multiple GraphQL endpoints (you can read more about that in this blogpost). But for our purpose we are happy with just the proxying. Finally, graphql-playground-middleware-express will give us an endpoint for the GraphQL Playground IDE.

Step 2: Get your API details

Within the Appsync console, navigate to the Schema tab, click Export schema and choose schema.graphql. Save it to your project directory, rename the file to schema.js. Surround schema with backticks and export the string, so it will look like this:

// schema.js
module.exports = `
  <YOUR SCHEMA HERE>
`;

Now we just need the URL and Api key. Back in the Appsync console, navigate to the Settings tab and copy your API URL and a valid API key. Alternatively, if you've used Amplify to setup your API you can also get theses details by running amplify status from your terminal. You can put these values in a .env file which you can read with dotenv, but for this example we'll just put them in a javascript file:

// settings.js
module.exports = {
  API_KEY: "<your api key here>",
  API_URL: "<your endpoint here>"
};

Don't forget to add this file to your .gitignore if you're using git!

Step 3: The code

Now all that's left to do is write a little express server:

// server.js
const express = require("express");
const registerServices = require("@workpop/graphql-proxy").default;
const expressPlayground = require("graphql-playground-middleware-express").default;
const types = require("./schema.js");
const { API_KEY, API_URL } = require("./settings.js");

const SERVICE_CONFIG = {
  APPSYNC: {
    address: API_URL,
    typeDefs: types
  }
};

const PORT = 4000;
const app = express();
app.get("/playground", expressPlayground({ endpoint: "/graphql" }));

registerServices({
  SERVICE_CONFIG,
  server: app,
  masterTypeDefs: types,
  customHeaders: {
    "x-api-key": API_KEY
  },
  enableGrqphiQL: true
}).then(() => {
  app.listen(PORT, () =>
    console.log(
      `Running playground proxy on http://localhost:${PORT}/playground`
    )
  );
});

Now start your server with node server.js et voila. Happy querying!

Edit:
Note that AppSync might have some AWS directives in your exported schema which graphql-proxy cannot recognize, so you will have to remove those manually.

Top comments (8)

Collapse
 
rebelok profile image
Andrew Vdovichenko

Hi @peerhenry !
I've tried to follow your article to setup playground, but when I run it I get this error, when @workpop/graphql-proxy is required:

internal/modules/cjs/loader.js:1033
throw err;
^
Error: Cannot find module 'babel-runtime/regenerator'

So I wonder: do I miss a step/dependency/version to have it working?

Collapse
 
peerhenry profile image
peerhenry

Hi @rebelok ,

It looks like your using Babel to transpile your javascript, which means you need to do a little extra configuration in order to get it to work with Promises.
Check you babel version, if <7.4.0 you will need: npm install --save @babel/polyfill and in as early as possible in your code: require("@babel/polyfill");.
For later versions you can use import "core-js/stable"; and import "regenerator-runtime/runtime";
See this page at babeljs.io for more information.

Collapse
 
rebelok profile image
Andrew Vdovichenko

I didn't add any code except the code from the article ^_^

Thread Thread
 
peerhenry profile image
peerhenry

Hmm, I could not reproduce the issue. Can you tell me what node version you are using and what are the dependencies listed in package.json?

Thread Thread
 
rebelok profile image
Andrew Vdovichenko

Here is the repository: github.com/rebelok/graphql-playground
I've tried on nodes 8, 10, 12 and 14 - the result is the same ^_^

Thread Thread
 
peerhenry profile image
peerhenry • Edited

I was able to fix the issue by installing npm i -S babel-runtime. Apparently it's a peer dependency of @workpop/graphql-proxy, meaning it doesn't get installed alongside of it. (The only reason I didn't run into this earlier is because node was able to resolve it from an underlying folder on my end.) I will update the article, thanks for bringing it to my attention. Let me know if this fixes the issue for you as well.

Collapse
 
loganpowell profile image
Logan Powell

Hi @peerhenry ! Thank you for the concise and perfectly timed post! I hit a snag and was wondering if you ran into a similar issue:

github.com/aws-amplify/amplify-js/...

Any follow up would be so very much appreciated!

Collapse
 
peerhenry profile image
peerhenry

Hi @loganpowell . It seems that bundling graphql with a tool like parcel or webpack can cause this issue. Perhaps you can find a solution by tweaking your minification and/or mangling settings.