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!