GraphQL Remote Loader

Performant, batched GraphQL queries from within the resolvers of a graphql-ruby API.

Example

  field :repositoryUrl, !types.String do
    description "The repository URL"

    resolve ->(obj, args, ctx) do
      query = "        node(id: \"\#{obj.global_relay_id}\"){\n          ... on Repository {\n            url\n          }\n        }\n      GQL\n\n      GitHubLoader.load(query).then do |results|\n        results[\"node\"][\"url\"]\n      end\n    end\n  end\n"

Description

graphql-remote_loader allows for querying GraphQL APIs from within resolvers of a graphql-ruby API.

This can be used to create GraphQL APIs that depend on data from other GraphQL APIs, either remote or local.

A promise-based resolution strategy from Shopify's graphql-batch is used to batch all requested data into a single GraphQL query. Promises are fulfilled with only the data they requested.

You can think of it as a lightweight version of schema-stitching.

How to use

First, you'll need to install the gem. Either do gem install graphql-remote_loader or add this to your Gemfile:

gem "graphql-remote_loader"

The gem provides a base loader GraphQL::RemoteLoader::Loader which does most of the heavy lifting. In order to remain client-agnostic, there's an unimplemented no-op that queries the external GraphQL API.

To use, create a new class that inherits from GraphQL::RemoteLoader::Loader and define def query(query_string). The method takes a query String as input. The expected output is a response Hash, or some object that responds to #to_h.

Example:

require "graphql/remote_loader"

module MyApp
  class GitHubLoader < GraphQL::RemoteLoader::Loader
    def query(query_string)
      parsed_query = MyApp::Client.parse(query_string)
      MyApp.query(parsed_query)
    end
  end
end

This example uses graphql-client. Any client, or even just plain cURL/HTTP can be used.

Current State

This project is very much WIP. Some TODOs are listed in the issues. Bugs and feature requests should be added as issues.