Debugging complex GraphQL queries with shortlinks to GraphiQL

Here's how you can create shortlinks in your terminal, so you can quickly open incoming GraphQL queries in the GraphiQL editor.

Please read through this code and I'll explain below.

server.js

const express = require('express')
const graphqlHTTP = require('express-graphql')
const { buildSchema } = require('graphql')
const hash = require('object-hash')
const bodyParser = require('body-parser')
const querystring = require('querystring')

// Construct a schema, using GraphQL schema language
const schema = buildSchema(`
  type Query {
    hello: String
  }
`)

// The root provides a resolver function for each API endpoint
const root = {
  hello: () => {
    return 'Hello world!'
  }
}

const app = express()

// parses incoming json post requests, and
// makes it available on req.body.
app.use(bodyParser.json());

/**
 * Enable shortlinks in the terminal  which will automatically
 * take you to graphiql editor pre-filled with data.
 */
if (process.env.NODE_ENV === 'development') {

  const queryLog = {}

  // parses shortlinks and redirects to the GraphiQL editor
  app.use('/goto', (req, res) => {
    const { id } = req.query
    if (!queryLog[id]) {
      console.error('Failed to find a stored query')
      return res.status(404).end()
    }
    return res.redirect(queryLog[id])
  })

  // peeks at incoming /graphql requests and builds shortlinks
  app.use('/graphql', (req, res, next) => {
    const { query, variables } = req.body
    const queryParams = querystring.stringify({
      query,
      variables: JSON.stringify(variables)
    })
    // hash query into id so that identical queries occupy
    // the same space in the queryLog map.
    const id = hash({ query, variables })
    queryLog[id] = `http://localhost:4000/graphql?${queryParams}`
    console.log(
      'Query was made, inspect:',
      `http://localhost:4000/goto?id=${id}`
    )
    // finally pass requests to the actual /graphql endpoint
    next()
  })
}

app.use(
  '/graphql',
  graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true
  })
)

app.listen(4000)
console.log('Running a GraphQL API server at http://localhost:4000/graphql')

The code above intercepts calls to /graphql and uses the incoming json data to construct a link to the GraphiQL editor. You could output the GraphiQL link directly to the terminal, but that will be quite noisy, especially if you're dealing with complex queries with several variables. Thus we hash the query and give ourselves nice shortlinks.

Here's a screenshot of the server.js code running in my terminal.

The code above running in my terminal showing how I get clickable links.

Nice clickable links that take you directly to a pre-filled GraphiQL editor.

In most terminals (and hopefully yours) you can click these links, and you'll get sent to you GraphiQL editor pre-filled with the query and any accompanying variables.

Huzzah! Those contorted GraphQL queries and obscure input variables will hound you no more. Now you can quickly debug them.