GraphQL Join or how to find all bars around GraphQL Summit with a single query

Ivan Goncharov
APIs.guru
Published in
4 min readOct 24, 2017

--

If you visited a couple of developer conferences you should know that the most fun part is not the talks but the bar crawl after the event.

So how to find all the bars near GraphQL Summit location? A quick and simple answer would be to just copy the address from official website and paste it into Yelp or FourSquare.

But you don’t need to be a GraphQL guru to do that. How about using GraphQL for getting this data?

We will do this using the following master plan:

  1. Get the address of venue. Fortunately, Universe recently released GraphQL API for their catalog of events:

2) Find all bars around this venue. No surprise, here we will just use Yelp’s GraphQL API:

Bingo! Problem is solved we get all the necessary data exclusively from GraphQL APIs. But can we reduce it to a single query? What if we could just join two GraphQL APIs together?

Joining GraphQL APIs is a hot topic at the moment and most likely you have already heard about schema stitching concept presented by Apollo. We really like the idea but the complexity of code you have to write looks a bit scary. So we decided to build a new tool from scratch with the idea to join APIs using familiar GraphQL syntax (queries, fragments, IDL) in declarative fashion — GraphQL Join.

GraphQL Join requires some polishing before the public release but we would like to get feedback about our declarative syntax before. So let’s get familiar with it by stitching Universe and Yelp APIs together in exactly 40 lines:

Configuration

Everything can be configured inside a single YAML file which has three top level properties apis , joinIDL and transformModule . Let’s describe them one by one:

  1. apis: Specify APIs to join and how the can be accessed

GraphQL Join sends introspection query to each of those APIs server to allow reusing remote types in resulting API. We also added support for prefixing types to avoid name clashes if needed (see prefix property). It’s a good idea to prefix types of API you don’t have control over, e.g. we add prefix Yelp_ to all types from Yelp.

To store access tokens outside of config files and provide them through environment variables we support special construct: ${env: VARIABLE_NAME}

2) joinIDL: Describe how to merge two APIs together:

Does it look familiar? Yes, we used mixture of standard GraphQL IDL, Query syntax and @export directive (used by Facebook for batching). The only new things we’ve added are @resolveWith and @send directives.

But let’s go step by step.

Here we decide what will be the root type of our joined API. And we specify Query which is non-prefixed Query type from Universe API (if we wanted to to do the same with Yelp, we should have used Yelp_Query).

This will effectively copy all the Universe API. Next, let’s extend it with the data from Yelp:

Here we are adding placesNearby field into Event type. Note that the field return type is Yelp_Businesses.

New field is resolved by sending getPlacesNearby query to Yelp API with extra arguments provided by LocationForYelp fragment:

3) transformModule: Transform arguments. One strange thing you’ve probably noticed is that LocationForYelp exports address and cityName variables but getPlacesNearby query expects those two as a single location argument. Sadly we can’t use our declarative syntax for this transformation and need to write a few lines of JS:

You can see whole join.yaml and join.js files here and start your new join API with a single command:graphql-join ./universe_yelp/join.yaml

Try it out

Let’s test the resulting API with a query I promised you in the title:

You can play with this API yourself: http://universe-yelp.apis.guru/

Features

Here is the list of what features are already implemented in GraphQL Join:

  • Full support of GraphQL queries: aliases, fragments, query variables, etc.
  • All request against GraphQL APIs are batched and no special support from your GraphQL server is required.
  • Our proxy is absolutely transparent both for the client and the original server. You can even use new joined API to join it with any other API.

What’s next

For the public release we want to ship it together with a slick UI for creating configuration with blackjack and autocompletion 😀.

Our main goal is to define declarative syntax for joining GraphQL APIs which is easy to read and has smooth learning curve. Would be great to get your feedback in comments or in person during GraphQL Summit!

--

--