Filling in the GraphQL pipeline: Ready-to-use code generation

Sean Grove
Sean GroveMay 3rd, 2019

For our OneGraph users, we want to shorten the time from idea → production-ready execution as much as possible. We’ve invested heavily in our explorer tooling to make the very first stage of integrating with an API joyous, so that today a developer can go from zero-knowledge of the data an API has - and even zero-knowledge of GraphQL itself - to exploring and retrieving data instantly.

Today’s release reduces the time from exploring, to running fully-working-code. In particular, with the OneGraph Code Exporter, as you build up your working queries inside of GraphiQL, we’ll build up the corresponding code for you to use automatically. You can use the code immediately - with no alteration - in your apps directly.

You can also check out a video preview of the new GraphiQL Code Exporter

We’ve been testing the exporter feature with our users for awhile now, and it’s already been put to great use by people like Kyle Matthews, the creator of Gatsby.js, as he wrote about in his post Building a Slack bot to help handle large numbers of PRs!

Let’s talk about why this is the tooling our community needs now.

The GraphQL pipeline as part of the app development life-cycle

The lifecycle for a developer using GraphQL follows a very common pattern:

10 Learn syntax and semantics

20 Discover what data is available

30 Build queries to select desired data

40 Embed working queries into an app (on the frontend or the backend)

50 Confirm that the query data matches up with the desired data and the code works

60 GOTO 20

OneGraph’s GraphiQL Explorer focused on helping discovery and building, and made it lots of fun to see real data coming out of our upstream APIs with so little effort. Still, for so many users (especially those new to GraphQL) embedding is a daunting task.

Today we’re tackling this gap in the GraphQL pipeline.

Extending GraphiQL Again

Just like our explorer, the OneGraph Code Exporter is an open-source component designed to extend the fantastic community-standard tool, GraphiQL.

GraphiQL is an exploratory tool that’s great for building up and testing queries, seeing the types of each individual field, being able to search through a schema for a field name or type, and even read the docs inline.

GraphiQL is a core component of OneGraph’s data explorer, and is the very first experience many of our users have with GraphQL at all.

Bridging The Gap

The GraphQL experience from early exploration to immediate results is exhilarating and well-paved at this point, but after your developers have built a working query, what’s next? To actually use those queries, they’ll need to setup their client-side connection, handle the fetching logic, the loading and errors state, and so on.

That’s painful in two critical ways: For experienced developers, there’s a lot of repeated typing - find a previous working query, copy it, paste it into a new module, replace the query with the one you’ve just built (don’t forget to update the variables and operationId!). It’s quite a bit of overhead for each query!

Perhaps even more importantly however, for new users it’s the equivalent of running into a brick wall. They were flowing along, exploring data, seeing results, and now… how do they turn this example into a real app?

Code Exporter

Today, to help fill in the missing gaps, we’re open-sourcing another contribution for the wider GraphQL community - our graphiql-code-exporter! It generates ready-to-run code snippets from your GraphiQL queries, as you build them. The feedback is instantaneous!

It ships with two example snippets, one for react-apollo and another for simple fetch (both client and server-side usage).

GraphiQL using the graphiql-code-exporter plugin to generate a ready-to-use snippet for react-apollo

Customizable for your team and your developers But more than the explorer, the OneGraph Code Exporter is meant to be customized by your team with your own patterns. By writing your own snippet function, you’ll ensure two critical points:

  1. Smooth developer experience with your GraphQL service throughout the full app development lifecycle, joyous from start to finish
  2. Well-baked patterns will be used consistently throughout your app, preventing edge cases from building up

Of course, it’s open source and hosted on GitHub. Feel free to dig in, contribute new snippets, and most important: share it so everyone can enjoy it! We’d love to see snippets for alternative clients like Grafoo and languages like Ruby!

Automations that increase user competency1

A guiding principle in the tooling OneGraph builds is that automation doubles a chance to teach. For example, with our GraphiQL Explorer, people can gradually learn the syntax for complex GraphQL queries through a simple visual selection. And now with the code exporter, we have a chance to teach users some nifty features as well. Consider this simple query:

{
  rss {
    rss2Feed(url: "https://www.heavybit.com/category/library/podcasts/jamstack-radio/feed") {
      title
      description
      items {
        title
        description
        link
      }
    }
  }
}

The query does work as-is, but there are a few ways it could be improved - for instance, the query could be named so that its performance over time can be monitored. We still want to generate code that’ll work without any user intervention:

const operationsDoc = `
  # Consider giving this query a unique, descriptive
  # name in your application as a best practice
  # see https://stackoverflow.com/a/52542928/610345 for more information
  query unnamedQuery1 {
    rss {
      rss2Feed(url: "https://www.heavybit.com/category/library/podcasts/jamstack-radio/feed") {
        title
        description
        items {
          title
          description
          link
        }
      }
    }
  }
`;

But note how in the generated code, we take the opportunity to do two things: 1. Give a user-readable note that it’s possible and advantageous if they give the query a unique name 2. Automatically insert unnamedQuery1 to show an example of the syntax for naming queries

So if the user is in a hurry, they can copy/paste the (full) example and it’ll work straight-away, but there are bread-crumbs left for how to improve for later, when they have more time and want to dive deeper.

How it works

Under the hood, the code exporter monitors the current GraphiQL document (all of the queries, mutations, and fragments). Each time the document is updated, the code exporter is passed the new query, parses it using the community standard graphql-js, and re-renders. graphql-js packs awesome compiler tools that transform query documents from strings into data-structures with all the metadata we need to build great, responsive developer tooling. Once we have the data-structure, we can easily pick out different operations, grab their name, and figure out if they’re a query , a mutation, or a subscription.

Code libraries and styles are unique, and different operations change how you code your app - how your service handles client authentication (a header with a bearer token? JWT? Maybe cookie-based?), how you use variables, multiple operation names, etc.

With all that in mind, a snippet is a JavaScript object that defines two things:

  1. A data structure of list of options (rendered as checkboxes) that the user can select, e.g. whether to include comments, include boilerplate setup, or if the user intends to run the snippet to server-side, or in the browser.
  2. A function that receives all the user inputs from #1, and also the query name, body, variables, etc.

That’s enough to get ready-to-user snippets for most languages we’ve added so far. For example, a fetch snippet implementation is able to include comments, setup, and include a polyfill in order to run server-side since Node doesn’t implement fetch natively.

Let’s see exactly how this snippet is implemented so that you can see how quickly you can customize the GraphiQL experience for your developers.

An Example Snippet Apart from a function definition and UI requirements, a snippet also defines a snippet name (fetch or react-apollo-hooks), and the name of the programming language (JavaScript or Python) so that similar snippets are grouped together and output code is highlighted properly (using the built-in highlighting of code-mirror).

Check out one of my favorite, the bash/curl example - showing how you can use GraphQL directly from the command-line!

Contribute Your General Snippets

You can contribute snippets for your own preferred language or library in two ways: If it’s a snippet that can be used generally, feel free to submit it to the GraphiQL Code Exporter repository directly.

Contribute Your OneGraph Snippets

The second way to contribute is to submit snippets that are specific to a service. In OneGraph’s case, we’d love to have your snippets showing users how to use OneGraph in all languages and frameworks! Simply submit your OneGraph snippets to the OneGraph GraphiQL Exporter repository to help others go from exploring to production on OneGraph seamlessly - I personally can’t wait to see snippets for using OneGraph in Rust (wasm GraphQL?! what what?), Elm, and Elixir!

Other services will similarly benefit - Gatsby, Hasura, PostGraphile, AppSync, SourceGraph, and others!

Try it out for yourself!

We hope you love the exporter as much as we do! It’ll supercharge your developer experience, accelerate time to market, and reduce one-off bugs in your applications, especially for GraphQL newcomers. Check out the example repository to see how to add it to your GraphiQL instance!

A special thanks The OneGraph Code Exporter was requested by one of our earliest users, Sebastian Bensusan while integrating OneGraph with an isomorphic Clojure(Script** app. We haven’t added ClojureScript yet, and we’d love for the community to pick up the mantle!

Also, the bulk of the work was originally done by Robin Frischmann who explored the idea and language implementations deeply to find a model that that balanced flexibility, correctness, and developer-friendliness - thank you Robin!

Another approach The guild has also been working on this with https://graphql-code-generator.com - we're hoping to combine efforts at some point in the future!