An example GraphQL server implementation in Ruby
This project uses Sinatra, Sequel and the graphql-ruby
gem to create a Postgres-backed GraphQL server in Ruby. It implements the HTTP protocol outlined in the GraphQL HTTP best practices.
You can try it out on Heroku.
bundle install
Setup a local database:
bundle exec rake db:migrate
Add some seed data:
bundle exec rake db:seed
Start the server:
bundle exec ruby app.rb
This will start a server running with a GraphQL endpoint at http://localhost:4567/graphql and the GraphiQL tool at http://localhost:4567.
The data model represents a simple video-on-demand service that displays shows, seasons and episodes.
type Show {
id: ID!
title: String!
seasons: [Season]!
episodes: [Episode]!
}
type Season {
id: ID!
title: String!
number: Int!
episodes: [Episode]!
}
type Episode {
id: ID!
title: String!
number: Int!
show: Show!
season: Season!
}
Let's create a simple GraphQL query in a query.graphql
file that returns all of the shows:
{
shows {
id
title
}
}
We can run that query against the server using curl
:
curl -X POST http://localhost:4567/graphql \
-H 'Content-Type: application/graphql' \
-d @query.graphql | jq .
Here we're using
jq
(brew install jq
) to get a pretty-printed JSON output
The output of the curl
command will look like:
{
"data": {
"shows": [
{
"id": "b013pqnm",
"title": "The Great British Bake-Off"
},
{
"id": "b0071b63",
"title": "The Apprentice"
},
{
"id": "b062r9t5",
"title": "People Just Do Nothing"
}
]
}
}
We can then modify the query to return the nested episodes in each show:
{
shows {
id
title
episodes {
id
number
title
}
}
}
Which returns:
{
"data": {
"shows": [
{
"id": "b013pqnm",
"title": "The Great British Bake-Off",
"episodes": [
{
"id": "b07r246c",
"number": 1,
"title": "Cake Week"
},
{
"id": "b07tj10j",
"number": 2,
"title": "Biscuit Week"
},
{
"id": "b07v324h",
"number": 3,
"title": "Bread Week"
}
]
},
{
"id": "b0071b63",
"title": "The Apprentice",
"episodes": [
{
"id": "b07ynzyc",
"number": 1,
"title": "Collectables"
},
{
"id": "b07zfh1b",
"number": 2,
"title": "Advertising - Jeans"
},
{
"id": "b0806vqc",
"number": 3,
"title": "Corporate Candy"
}
]
},
{
"id": "b062r9t5",
"title": "People Just Do Nothing",
"episodes": [
{
"id": "p043m903",
"number": 1,
"title": "Dubplate"
},
{
"id": "b07tl80w",
"number": 2,
"title": "Record Deal"
},
{
"id": "p045280q",
"number": 3,
"title": "Court Case"
}
]
}
]
}
}
We can use arguments on the episodes
field to return only the latest episode in each show:
{
shows {
id
title
episodes(limit: 1, sortDirection: DESC) {
id
number
title
}
}
}
{
"data": {
"shows": [
{
"id": "b013pqnm",
"title": "The Great British Bake-Off",
"episodes": [
{
"id": "b07v324h",
"number": 3,
"title": "Bread Week"
}
]
},
{
"id": "b0071b63",
"title": "The Apprentice",
"episodes": [
{
"id": "b0806vqc",
"number": 3,
"title": "Corporate Candy"
}
]
},
{
"id": "b062r9t5",
"title": "People Just Do Nothing",
"episodes": [
{
"id": "p045280q",
"number": 3,
"title": "Court Case"
}
]
}
]
}
}
We can query for a particular show:
{
show(id: "b013pqnm") {
id
title
}
}
{
"data": {
"show": {
"id": "b013pqnm",
"title": "The Great British Bake-Off"
}
}
}
And then retrieve its entire hierarchy, including seasons and episodes:
{
show(id: "b013pqnm") {
id
title,
seasons {
id
title
number
episodes {
id
title
number
}
}
}
}
{
"data": {
"show": {
"id": "b013pqnm",
"title": "The Great British Bake-Off",
"seasons": [
{
"id": "b07r2pr0",
"title": "Series 7",
"number": 7,
"episodes": [
{
"id": "b07r246c",
"title": "Cake Week",
"number": 1
},
{
"id": "b07tj10j",
"title": "Biscuit Week",
"number": 2
},
{
"id": "b07v324h",
"title": "Bread Week",
"number": 3
}
]
}
]
}
}
}
We can also a retrieve an episode by its ID:
{
episode(id: "p043m903") {
id
number
title
}
}
{
"data": {
"episode": {
"id": "p043m903",
"number": 1,
"title": "Dubplate"
}
}
}
And return its season and show:
{
episode(id: "p043m903") {
id
number
title
season {
id
title
}
show {
id
title
}
}
}
{
"data": {
"episode": {
"id": "p043m903",
"number": 1,
"title": "Dubplate",
"season": {
"id": "p043m8g0",
"title": "Series 3"
},
"show": {
"id": "b062r9t5",
"title": "People Just Do Nothing"
}
}
}
}
The server includes the GraphiQL tool.
You can use it to explore the API in your browser by visiting http://localhost:4567/.
The GraphiQL installation follows the official example.
To use Shotgun to reload the server in development:
bundle exec shotgun
All SQL queries are logged by default in development. This is disabled when the RACK_ENV
environment variable is missing or set to production
.