GraphQL Client by GitHub is a Ruby library for declaring, composing and executing GraphQL queries.
Add graphql-client
to your Gemfile and then run bundle install
.
# Gemfile
gem 'graphql-client'
Sample configuration for a GraphQL Client to query from the SWAPI GraphQL Wrapper.
Tip:
Always remember to replace
API_SECRET
in the Bearer Token andproject-id
in the URL with the correct values from the Apito console.
If you are unsure where to find your API secrets and endpoints for your project, visit this page.
require "graphql/client"
require "graphql/client/http"
# Star Wars API example wrapper
module SWAPI
# Configure GraphQL endpoint using the basic HTTP network adapter.
HTTP = GraphQL::Client::HTTP.new("https://api.apito.io/secured/graphql") do
def headers(context)
# Must Set the Authorization Headers
{ "Authorization": "Bearer API_SECRET" }
end
end
# Fetch latest schema on init, this will make a network request
Schema = GraphQL::Client.load_schema(HTTP)
# However, it's smart to dump this to a JSON file and load from disk
#
# Run it from a script or rake task
# GraphQL::Client.dump_schema(SWAPI::HTTP, "path/to/schema.json")
#
# Schema = GraphQL::Client.load_schema("path/to/schema.json")
Client = GraphQL::Client.new(schema: Schema, execute: HTTP)
end
If you haven't already, familiarize yourself with the GraphQL query syntax. Queries are declared with the same syntax inside of a <<-'GRAPHQL'
heredoc. There isn't any special query builder Ruby DSL.
This client library encourages all GraphQL queries to be declared statically and assigned to a Ruby constant.
HeroNameQuery = SWAPI::Client.parse <<-'GRAPHQL'
query {
hero {
name
}
}
GRAPHQL
Queries can reference variables that are passed in at query execution time.
HeroFromEpisodeQuery = SWAPI::Client.parse <<-'GRAPHQL'
query($episode: Episode) {
hero(episode: $episode) {
name
}
}
GRAPHQL
Fragments are declared similarly.
HumanFragment = SWAPI::Client.parse <<-'GRAPHQL'
fragment on Human {
name
homePlanet
}
GRAPHQL
To include a fragment in a query, reference the fragment by constant.
HeroNameQuery = SWAPI::Client.parse <<-'GRAPHQL'
{
luke: human(id: "1000") {
...HumanFragment
}
leia: human(id: "1003") {
...HumanFragment
}
}
GRAPHQL
This works for namespaced constants.
module Hero
Query = SWAPI::Client.parse <<-'GRAPHQL'
{
luke: human(id: "1000") {
...Human::Fragment
}
leia: human(id: "1003") {
...Human::Fragment
}
}
GRAPHQL
end
::
is invalid in regular GraphQL syntax, but #parse
makes an initial pass on the query string and resolves all the fragment spreads with constantize
.
Pass the reference of a parsed query definition to GraphQL::Client#query
. Data is returned back in a wrapped GraphQL::Client::Schema::ObjectType
struct that provides Ruby-ish accessors.
result = SWAPI::Client.query(Hero::Query)
# The raw data is Hash of JSON values
# result["data"]["luke"]["homePlanet"]
# The wrapped result allows to you access data with Ruby methods
result.data.luke.home_planet
GraphQL::Client#query
also accepts variables and context parameters that can be leveraged by the underlying network executor.
result = SWAPI::Client.query(Hero::HeroFromEpisodeQuery, variables: {episode: "JEDI"}, context: {user_id: current_user_id})
For a detailed guide, be sure to check out the official github page here