Ruby on Rails com GraphQL: Tutorial rápido
Veja como criar um App simples e rápido com Rails e GraphQL. Tutorial sem enrolação e direto ao ponto.
Começando o Desenvolvimento
Antes de começar quero deixar claro alguns dados do meu ambiente de desenvolvimento. Estou utilizando Ruby 2.5.1, Rails 5.2.1 e SQLite 3.
As Gems que serão utilizadas:
- graphql: Responsável por todas as definições de backend.
- graphiql-rails: Cliente Web utilizado para testes. Lembrando que esta Gem é opcional e seu uso só é recomendado no ambiente de desenvolvimento.
Modelagem
Este exemplo contém duas tabelas "People" e "Countries", onde uma pessoa pode pertencer a um país e um país pode possuir várias pessoas.
Para criar essas entidades utilizaremos os Scaffolds por meio dos seguintes comandos:
- rails g model country name:string continent:string
- rails g model person name:string country:references
Não se esqueça de executar rails db:migrate .
Configurando o GraphQL no Ruby on Rails
Após a instalação das Gems, você já pode começar a configurar o GraphQL com o comando rails g graphql:install .
Este comando criar as pastas e arquivos padrões do GraphQL dentro do ambiente Ruby on Rails. Além disso, também já configura a rota padrão e o Controller que será utilizado.
Esqueça as Rotas e Controllers
Programadores Ruby on Rails são acostumados a criar rotas e Controllers para cada recurso necessário. Com GraphQL você pode esquecer isso.
Todas as requisições serão centralizadas em apenas um EndPoint, ou seja, apenas uma rota e um Controller. Lembrando que isso faz parte do padrão do GraphQL.
Antes de continuar
Antes de continuar você precisa saber o que são Types, Queries e Mutations. Caso você não saiba, recomendo que leia este texto: Clique Aqui.
Configurando os Types e Queries
Primeiramente vamos criar o tipo Country: app/graphql/types/country_type.rb
module Types
class CountryType < Types::BaseObject
field :id, ID, null: false
field :name, String, null: true
field :continent, String, null: true
field :people, [Types::PersonType], null: true
end
end
Crie o tipo Person: app/graphql/types/person_type.rb
module Types
class PersonType < Types::BaseObject
field :id, ID, null: false
field :name, String, null: true
field :country, Types::CountryType, null: true
end
end
Agora só falta alterar o arquivo app/graphql/types/query_type.rb .
module Types
class QueryType < Types::BaseObject
# Add root-level fields here.
# They will be entry points for queries on your schema.
field :country, Types::CountryType, null: true do
argument :id, ID, required: true
end
def country(id:)
Country.where(id: id).first
end
field :countries, [Types::CountryType], null: true
def countries
Country.all
end
field :person, Types::PersonType, null: true do
argument :id, ID, required: true
end
def person(id:)
Person.where(id: id).first
end
field :people, [Types::PersonType], null: true
def people
Person.all
end
end
end
Mutations: Chegou a hora de alterar os dados
Ao todo vamos criar 6 Mutations. São 3 mutations para a entidade "Country" (create, update e delete) e 3 mutations para entidade "Person" (create, update e delete):
# app/graphql/mutations/create_country.rb
module Mutations
class CreateCountry < GraphQL::Schema::RelayClassicMutation
field :country, Types::CountryType, null: false
argument :name, String, required: true
argument :continent, String, required: true
def resolve(*args)
{
country: Country.create(args[0])
}
end
end
end
# app/graphql/mutations/update_country.rb
module Mutations
class UpdateCountry < GraphQL::Schema::RelayClassicMutation
field :country, Types::CountryType, null: false
argument :id, ID, required: true
argument :name, String, required: false
argument :continent, String, required: false
def resolve(id:,name:,continent:)
{
country: Country.update(id, {name: name, continent: continent})
}
end
end
end
# app/graphql/mutations/delete_country.rb
module Mutations
class DeleteCountry < GraphQL::Schema::RelayClassicMutation
field :success, Integer, null: false
argument :id, ID, required: true
def resolve(id:)
{
success: Country.delete(id)
}
end
end
end
# app/graphql/mutations/create_person.rb
module Mutations
class CreatePerson < GraphQL::Schema::RelayClassicMutation
field :person, Types::PersonType, null: false
argument :name, String, required: true
argument :country_id, Integer, required: true
def resolve(*args)
{
person: Person.create(args[0])
}
end
end
end
# app/graphql/mutations/update_person.rb
module Mutations
class UpdatePerson < GraphQL::Schema::RelayClassicMutation
field :person, Types::PersonType, null: false
argument :id, ID, required: true
argument :name, String, required: false
argument :country_id, Integer, required: false
def resolve(id:,name:,country_id:)
{
person: Person.update(id, {name: name, country_id: country_id})
}
end
end
end
# app/graphql/mutations/delete_person.rb
module Mutations
class DeletePerson < GraphQL::Schema::RelayClassicMutation
field :success, Integer, null: false
argument :id, ID, required: true
def resolve(id:)
{
success: Person.delete(id)
}
end
end
end
Por fim, vamos alterar o arquivo app/graphql/types/mutation_type.rb para disponibilizar as Mutations para os clientes.
module Types
class MutationType < Types::BaseObject
field :createCountry, mutation: Mutations::CreateCountry
field :updateCountry, mutation: Mutations::UpdateCountry
field :deleteCountry, mutation: Mutations::DeleteCountry
field :deletePerson, mutation: Mutations::DeletePerson
field :updatePerson, mutation: Mutations::UpdatePerson
field :createPerson, mutation: Mutations::CreatePerson
end
end
App Completo
O aplicativo completo está disponível no GitHub: Clique aqui.
Dúvidas ou sugestões é só entrar em contato. Abraço.