GraphQL + Rails na prática – Inputs customizados

No último posts da série GraphQL + Rails na prática vamos ver como criar tipos específicos para inputs que facilitam o reuso do código.

Voltando no arquivo que define as mutações (‘app/graphql/types/mutation_type.rb’) temos a seguinte definição de tipo para criar um novo jogo:

# app/graphql/types/mutation_type.rb
field :new_game do
  description 'Creates a new game'
  type Types::GameType
  argument :name, !types.String
  argument :launch_year, !types.String
  argument :description, types.String

  resolve -> (root, args, _ctx) do
    Game.create(name: args[:name],
                launch_year: args[:launch_year],
                description: args[:description])
  end
end

Imagine que os campos ‘name’, ‘launch_year’ e ‘description’ vão aparecer juntos em vários outros lugares podemos evitar duplicação criando um ‘InputObjectType’. A principal diferença do ‘ObjectType’ que usamos antes é que esses tipos podem ser utilizados como inputs, ao invés de retorno de consultas.

Criando inputs customizados

Crie uma nova pasta ‘app/graphql/inputs/’ e adicione um arquivo ‘game_input.rb’, nele vamos definir o novo tipo, agregando todos aqueles campos.

# app/graphql/inputs/game_input.rb
Inputs::GameInput = GraphQL::InputObjectType.define do
  name 'GameInput'
  description 'Game attributes'

  argument :name, !types.String
  argument :launch_year, !types.String
  argument :description, types.String
end

Agora basta utilizar esse novo tipo na mutação que cria um jogo:

# app/graphql/types/mutation_type.rb
field :new_game do
  description 'Creates a new game'
  type Types::GameType
  argument :game, Inputs::GameInput

  resolve -> (root, args, _ctx) do
    Game.create(name: args[:game][:name],
    launch_year: args[:game][:launch_year],
    description: args[:game][:description])
  end
end

Vale lembrar que essa modificação altera a forma como as consultas são feitas! A nova consulta deve ser assim:

mutation CreateGame {
  new_game(game:{name: "The Legend of Zelda", launch_year: "1986"}) {
    name
    launch_year
    description
  }
}

Se você quiser evitar uma mudança destrutiva na sua API uma ideia é criar uma nova mutação que usa o tipo input, assim quem ainda precisar da consulta antiga consegue utilizá-la.

Podemos dar ainda mais uma passo e simplificar o ‘resolver’ da mutação que cria jogos aproveitando que, ao criar novas entradas com o ActiveRecord, é possível utilizar um hash com os parâmetros. Então o ‘resolver’ da mutação ‘new_game’ pode ficar com apenas uma linha:

# app/graphql/types/mutation_type.rb
field :new_game do
  description 'Creates a new game'
  type Types::GameType
  argument :game, Inputs::GameInput

  resolve -> (root, args, _ctx) do
    Game.create(args[:game].to_h)
  end
end

Com isso finalizamos o nosso tour de GraphQL + Rails com a mão na massa! Ainda tem muitas coisas legais que podem ser exploradas, como filtragem e paginação em consultas, autenticação e autorização na API, balanceamento de carga, consumir APIs GraphQL etc. Quem sabe numa próxima série de posts? 🙂

Se você quiser conhecer mais sobre GraphQL o site https://www.howtographql.com/ contém muita informação legal além de tutoriais em várias linguagens, então super recomendo a leitura.

Se você curtiu essa série me avisa lá no twitter e compartilha os posts com a galera que tá querendo colocar a mão na massa em GraphQL!

Deixe um comentário