menu

SHARKLABS

Ruby on Rails com GraphQL: Tutorial rápido

/
/
Ruby on Rails com GraphQL: Tutorial rápido
bookmark Ruby on Rails, GraphQL access_time

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.

Autor
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." Martin Fowler