GraphQL API Integration with Ruby Project
GraphQL Client by GitHub is a Ruby library for declaring, composing and executing GraphQL queries.
Installation
Add graphql-client
to your Gemfile and then run bundle install
.
# Gemfile
gem 'graphql-client'
Configuration
Sample configuration for a GraphQL Client to query from the SWAPI GraphQL Wrapper.
Always remember to replace API_SECRET
with the correct value that you copied from apito console.
Go to this page if you do not know where to find your api secrets for your project
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
Defining Queries
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
.
Executing queries
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})
Detailed Guide
For a detailed guide, be sure to check out the official github page here