The purpose of this example is to provide details as to how one would go about using GraphQL with the Ruby Language. Thus, I have created three major sections which should be self explanatory: Quick Installation, Docker Installation, and Tutorial Installation.
-
Docker Desktop 4.30.0 or newer
-
PostgreSQL 16.4 or newer
-
Rails 7.1.3.4 or newer
-
Ruby 3.3.6 or newer
Note: This tutorial was updated on macOS 15.1. Docker Desktop is ony needed if you're following the Docker Installation
.
- If you need help, use Stack Overflow. (Tag 'graphql')
- If you'd like to ask a general question, use Stack Overflow.
- If you found a bug, open an issue.
- If you have a feature request, open an issue.
- If you want to contribute, submit a pull request.
-
clone this repository
git clone git@github.com:conradwt/zero-to-graphql-using-ruby.git
-
change directory location
cd zero-to-graphql-using-ruby
-
install dependencies
bundle install
-
create, migrate, and seed the database
rails db:setup
-
start the server
rails s
-
navigate to our application within the browser
open http://localhost:3000/graphiql
-
enter the below GraphQL query on the left side of the browser window
{ person(id: "1") { firstName lastName username email friends { firstName lastName username email } } }
-
run the GraphQL query
Control + Enter
Note: The GraphQL query is responding with same shape as our GraphQL document.
-
clone this repository
git clone git@github.com:conradwt/zero-to-graphql-using-ruby.git
-
change directory location
cd zero-to-graphql-using-ruby
-
start all services
docker compose up -d
-
create, migrate, and seed database
docker compose exec app bin/rails db:setup
-
navigate to our application within the browser
open http://localhost:3000/graphiql
-
enter the below GraphQL query on the left side of the browser window
{ person(id: "1") { firstName lastName username email friends { firstName lastName username email } } }
-
run the GraphQL query
Control + Enter
Note: The GraphQL query is responding with same shape as our GraphQL document.
-
cleanup
docker compose down docker system prune -a --volumes
-
create the project
rails new zero-ruby -d postgresql --skip-active-storage --skip-javascript -T --no-rc
-
rename the project directory
mv zero-ruby zero-to-graphql-using-ruby
-
switch to the project directory
cd zero-to-graphql-using-ruby
-
update Ruby gem dependencies
bundle add rack-cors
-
add CORS initializer by adding the following text within the
config/initializers/cors.rb
file:Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins '*' resource '*', headers: :any, methods: %i[get post put patch delete options head] end end
-
Add the following after the
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
setting withindatabase.yml
:host: <%= ENV.fetch("POSTGRES_HOST") { 'localhost' } %> username: <%= ENV.fetch("POSTGRES_USER") { 'postgres' } %> password: <%= ENV.fetch("POSTGRES_PASSWORD") { 'password' } %>
-
create the database
rails db:create
-
generate
Person
modelrails g model person first_name last_name username email
-
migrate the database
rails db:migrate
-
replace the generated
Person
model with the following:class Person < ApplicationRecord has_many :friendships, dependent: :destroy has_many :friends, through: :friendships end
-
generate a
Friendship
model which representing our join model:rails g model friendship person:references friend:references
-
replace
t.references :friend, foreign_key: true
, within migration file,<some-timestamp>_create_friendships.rb
file with the following:t.references :friend, index: true
-
migrate the database
rails db:migrate
-
replace the generated
Friendship
model with the following:app/models/friendship.rb
:class Friendship < ApplicationRecord belongs_to :person belongs_to :friend, class_name: 'Person' end
Note: We want
friend_id
to reference thepeople
table because ourfriend_id
really represents aPerson
model. -
update the contents of the seeds file to the following:
db/seeds.rb
:# reset the datastore Person.destroy_all # insert people me = Person.create!(first_name: 'Conrad', last_name: 'Taylor', email: 'conradwt@gmail.com', username: 'conradwt') dhh = Person.create!(first_name: 'David', last_name: 'Heinemeier Hansson', email: 'dhh@37signals.com', username: 'dhh') ezra = Person.create!(first_name: 'Ezra', last_name: 'Zygmuntowicz', email: 'ezra@merbivore.com', username: 'ezra') matz = Person.create!(first_name: 'Yukihiro', last_name: 'Matsumoto', email: 'matz@heroku.com', username: 'matz') me.friendships.create!(friend_id: matz.id) dhh.friendships.create!(friend_id: ezra.id) dhh.friendships.create!(friend_id: matz.id) ezra.friendships.create!(friend_id: dhh.id) ezra.friendships.create!(friend_id: matz.id) matz.friendships.create!(friend_id: me.id) matz.friendships.create!(friend_id: ezra.id) matz.friendships.create!(friend_id: dhh.id)
-
seed the database
rails db:seed
-
add
graphql
Ruby gem to yourGemfile
dependencies as follows:bundle add graphql --version '~> 2.3'
-
configure the graphql dependencies for our application
rails generate graphql:install
-
add the GraphQL schema which represents our entry point into our GraphQL structure:
app/graphql/zero_ruby_schema.rb
:# frozen_string_literal: true class ZeroRubySchema < GraphQL::Schema mutation(Types::MutationType) query(Types::QueryType) end
-
add our PersonType:
app/graphql/types/person_type.rb
:# frozen_string_literal: true module Types class PersonType < Types::BaseObject field :id, ID, null: false, description: 'unique identifier for the person' field :first_name, String, null: false, description: 'first name of a person' field :last_name, String, null: false, description: 'last name of a person' field :username, String, null: false, description: 'username of a person' field :email, String, null: false, description: 'email of a person' field :friends, [PersonType], null: false, description: 'a list of friends for our person' def friends object.friends end end end
-
update our QueryType to look like the following:
app/graphql/types/person_type.rb
:# frozen_string_literal: true module Types class QueryType < Types::BaseObject field :person, PersonType, null: true do description 'Find a person by ID' argument :id, ID, required: true end def person(id:) Person.find(id) end end end
-
add the following two lines to the bottom of our manifest file:
app/assets/config/manifest.js
://= link graphiql/rails/application.css //= link graphiql/rails/application.js
-
add routes for our GraphQL API and GraphiQL browser endpoints:
./config/routes.rb
:replace the contents with the following:
# frozen_string_literal: true Rails.application.routes.draw do if Rails.env.development? or Rails.env.test? mount GraphiQL::Rails::Engine, at: '/graphiql', graphql_path: '/graphql' end post '/graphql', to: 'graphql#execute' end
-
start the server
rails s
-
navigate to our application within the browser
open http://localhost:3000/graphiql
-
enter the below GraphQL query on the left side of the browser window
{ person(id: "1") { firstName lastName username email friends { firstName lastName username email } } }
-
run the GraphQL query
Control + Enter
Note: The GraphQL query is responding with same shape as our GraphQL document.
Ready to run in production? Please check our deployment guides.
- Official website: https://rubyonrails.org
- Guides: https://guides.rubyonrails.org
- Docs: https://api.rubyonrails.org
- Mailing list: https://groups.google.com/forum/#!forum/rubyonrails-talk
- Source: https://github.com/rails/rails
- Official Website: http://graphql.org
- GraphQL Ruby: https://graphql-ruby.org
- Docker Docs - https://docs.docker.com/reference
- Docker Compose - https://docs.docker.com/samples/rails
- How to setup Rails 6 on Docker - https://www.youtube.com/watch?app=desktop&v=XIjGbfcMAYM
Bug reports and feature requests can be filed with the rest for the Phoenix project here:
Zero to GraphQL Using Ruby is released under the MIT license.
copyright:: (c) Copyright 2019 - 2024 Conrad Taylor. All Rights Reserved.