GraphQL: mutations de atualização
Complete o CRUD da sua API GraphQL com mutations de atualização para pessoas, livros e comentários, usando novos tipos input com campos opcionais e Object.assign nos resolvers.
1. Visão geral
A operação mutation do GraphQL permite realizar as demais operações de um CRUD básico: inserção, atualização e remoção. Já fizemos inserções e remoções; neste material, implementamos as atualizações, completando o CRUD.
O que você vai aprender
- Definir mutations de atualização com novos tipos
inputde campos opcionais - Implementar os resolvers com
Object.assigne desestruturação de parâmetros - Testar as atualizações com valores fixos e com variáveis
O que você vai precisar
- O projeto do codelab "GraphQL: mutations de remoção e organização do projeto"
- Node.js, um editor de código e, opcionalmente, o Postman
2. Projeto da aula anterior e o modelo
Abra um terminal e navegue até o diretório do projeto. Use o comando a seguir para abri-lo no VS Code.
Terminal
code .
A seguir, coloque o servidor em execução com
Terminal
npm run start
Lembre-se que o script start está configurado para executar o nodemon, responsável pelo live reload feito quando atualizamos os arquivos da aplicação.
O modelo da aplicação que estamos utilizando é aquele exibido pela figura a seguir. Lembre-se que no projeto feito até então, as operações Query implementam os relacionamentos em modo bidirecional.

Figura 2.2.1: o modelo da aplicação.
3. Definindo as mutations de atualização
É possível que seja de interesse realizar operações de atualização de dados, o que irá completar a nossa implementação de um CRUD básico. Isso também pode ser feito por meio da especificação de mutations.
Começamos especificando as operações no arquivo schema.graphql. Teremos uma operação para cada tipo existente. Note que, além de especificar o id do "item" a ser atualizado, precisamos especificar os dados que desejamos atualizar. Para agrupá-los, definiremos novos objetos do tipo input. Não podemos reutilizar os já existentes pois eles possuem campos obrigatórios e, para o caso de atualizações, não necessariamente o usuário irá querer envolvê-los.
src/schema.graphql · Listagem 2.3.1 (trecho)
type Mutation {
inserirPessoa(pessoa: InserirPessoaInput!): Pessoa!
removerPessoa(id: ID!): Pessoa!
atualizarPessoa (id: ID!, pessoa: AtualizarPessoaInput!): Pessoa!
inserirLivro(livro: InserirLivroInput!): Livro!
removerLivro(id: ID!): Livro!
atualizarLivro (id: ID!, livro: AtualizarLivroInput!): Livro!
inserirComentario(comentario: InserirComentarioInput!): Comentario!
removerComentario(id: ID!): Comentario!
atualizarComentario(id: ID!, comentario: AtualizarComentarioInput!): Comentario!
}
input InserirPessoaInput {
nome: String!
idade: Int
}
input AtualizarPessoaInput {
nome: String
idade: Int
}
input InserirLivroInput {
titulo: String!
edicao: Int!
autor: ID!
}
input AtualizarLivroInput {
titulo: String
edicao: Int
}
input InserirComentarioInput {
texto: String!
nota: Int!
livro: ID!
autor: ID!
}
input AtualizarComentarioInput {
texto: String
nota: Int
}
4. Os resolvers de atualização
A seguir, implementamos os resolvers para cada operação no arquivo Mutation.js. Suas implementações são semelhantes àquelas referentes à inserção e remoção de dados. Repare que o terceiro parâmetro (o contexto) pode ser desestruturado diretamente na assinatura ({db}), assim como args ({id, livro}).
src/resolvers/Mutation.js · Listagem 2.3.2 (trecho)
...
},
atualizarPessoa (parent, args, {db}, info){
const pessoa = db.pessoas.find((p) => p.id === args.id);
if (!pessoa)
throw new Error ("Pessoa não existe");
Object.assign(pessoa, { nome: args.pessoa.nome || pessoa.nome, idade: args.pessoa.idade || pessoa.idade});
return pessoa;
},
inserirLivro(parent, args, ctx, info) {...
src/resolvers/Mutation.js · Listagem 2.3.3 (trecho)
...
,
atualizarLivro (parent, {id, livro}, ctx, info){
const {db} = ctx;
const livroExistente = db.livros.find (l => l.id === id);
if (!livroExistente)
throw new Error ("Livro não existe")
Object.assign(livroExistente, { titulo: livro.titulo || livroExistente.titulo, edicao: livro.edicao || livroExistente.edicao});
return livroExistente;
},
inserirComentario(parent, args, ctx, info) {...
src/resolvers/Mutation.js · Listagem 2.3.4 (final do arquivo)
…
,
atualizarComentario (parent, {id, comentario}, {db}, info){
const comentarioExistente = db.comentarios.find (l => l.id === id);
if (!comentarioExistente)
throw new Error ("Comentario não existe")
Object.assign (comentarioExistente, {
texto: comentario.texto || comentarioExistente.texto,
nota: comentario.nota || comentarioExistente.nota
});
return comentarioExistente;
}
}
export default Mutation;
5. Testando as atualizações
Para verificar se as operações de atualização de dados estão funcionando adequadamente, faça uma query e dê uma olhada em cada coleção. A seguir, faça a atualização de alguns campos de um item de cada coleção usando uma mutation e execute a query novamente. Uma query que você pode executar é dada a seguir.
GraphQL Playground ou Postman · Listagem 2.3.5
query {
pessoas{
id
nome
idade
}
comentarios {
id
texto
nota
}
livros{
id
titulo
edicao
}
}
A listagem a seguir mostra alguns exemplos de mutations que você pode utilizar para atualizar dados nas coleções.
GraphQL Playground ou Postman · Listagem 2.3.6
mutation {
atualizarPessoa (id: "1", pessoa: {
nome: "Sedgewick",
idade: 22
}){
id
nome
idade
}
atualizarLivro (id: "100", livro: {
titulo: "Algorithms II",
edicao: 2
}){
id
titulo
edicao
}
atualizarComentario (id: "1001", comentario: {
texto: "Muito bom mesmo",
nota: 5
}){
id
texto
nota
}
}
Lembre-se de executar novamente as queries para verificar o resultado nas coleções.
Com variáveis
Também é possível realizar testes utilizando variáveis, de modo que os valores a serem utilizados não fiquem fixos nas operações GraphQL. Veja um exemplo a seguir.
Listagem 2.3.7 (operação)
mutation ($id: ID!, $nome: String!, $idade: Int){
atualizarPessoa (id: $id, pessoa: {
nome: $nome,
idade: $idade
}){
id
nome
idade
}
}
Listagem 2.3.7 (variáveis)
{
"id": "1",
"nome": "Novo nome...",
"idade": 50
}
Caso necessário, a figura a seguir mostra como realizar essa mutation no Postman. O procedimento é análogo no Playground.

Figura 2.3.2: a mutation com variáveis no Postman.
6. Exercícios
- Conclua a definição de mutations para a sua aplicação, incluindo a operação de atualização.
7. Encerramento
Com as atualizações, sua API GraphQL tem um CRUD completo. No próximo codelab da série, você vai conhecer as subscriptions, que permitem ao servidor enviar dados ao cliente em tempo real.
Referências
- Babel · The compiler for next generation JavaScript. 2020. Disponível em https://babeljs.io. Acesso em agosto de 2020.
- GraphQL | A query language for your API. 2020. Disponível em https://graphql.org. Acesso em agosto de 2020.
- Node.js. 2020. Disponível em https://nodejs.org. Acesso em agosto de 2020.
- WILSON, Jim R. Node.js 8 the Right Way. 1st edition. The Pragmatic Programmers, LLC, 2018.