GraphQL is a another way to build your APIs.
First of all - I would say what GraphQL is not a REST “killer” or replacement for REST, it’s a completely different concept.
You can find a tons of “comparison” between REST and GrahpQL, and topics about “why” and “when” you should use it.
Let’s see some quick checkpoints:
- REST and GraphQL are totally different
- GraphQL isn’t a magic bullet, nor is it “better”
- You can use both at the same time
- GraphQL is great tools if used for the right thing
So, let’s start. As a example project, I’ll use my small pet project for our office purposes runboard.
Simple add graphql into your Gemfile.
gem 'graphql'
And run installer script. It creates some GraphQL specific files in your project.
rails generate graphql:install
routes.rb
post '/graphql', to: 'graphql#query'
So, we are ready to write our first queries.
All root queries we should describe in QueryType Type, for example like this:
#/app/graphql/types/query_type.rb
Types::QueryType = GraphQL::ObjectType.define do
name "Query"
field :users, !types[Types::UserType] do
argument :limit, types.Int, default_value: 10, prepare: -> (limit) { [limit, 30].min }
resolve -> (obj, args, ctx) {
User.limit(args[:limit]).order(id: :desc)
}
end
field :projects, !types[Types::ProjectType] do
argument :limit, types.Int, default_value: 10, prepare: -> (limit) { [limit, 30].min }
resolve -> (obj, args, ctx) {
Project.limit(args[:limit]).order(id: :desc)
}
end
end
Nothing unclear here, right? Simple ActiveRecord queries in field blocks.
After that, we need to create our first Type for our User and Project models:
#/app/graphql/types/user_type.rb
Types::UserType = GraphQL::ObjectType.define do
name 'User'
field :id, !types.ID
field :login, !types.String
field :bio, types.String
field :avatar, types.String
field :phone, types.String
field :position, types.String
field :name, types.String
field :email, types.String
field :projects, !types[Types::ProjectType] do
argument :limit, types.Int, default_value: 10, prepare: -> (limit) { [limit, 30].min }
resolve -> (obj, args, ctx) {
obj.projects.limit(args[:limit])
}
end
field :updated_at do
type types.Int
resolve -> (obj, args, ctx) {
obj.updated_at.to_i
}
end
field :created_at do
type types.Int
resolve -> (obj, args, ctx) {
obj.created_at.to_i
}
end
end
#/app/graphql/types/query_type.rb
Types::ProjectType = GraphQL::ObjectType.define do
name 'Project'
field :id, !types.ID
field :title, !types.String
field :description, !types.String
field :logo, !types.String
end
After that, we are ready for our queries!
P.S You can use web graphiql or desktop version.