Criando API GraphQL com .Net Core parte 2

Jozimar Back
4 min readApr 12, 2020

Olá a todos. Como prometido no meu post anterior sobre criação de API GraphQL com dotnet core, neste post irei demonstrar como implementar as mutations. Mutation em GraphQL é uma forma de comunicação com a API a fim de realizar interações com dados como inserção, alteração e remoção.

Photo by Karl Pawlowicz on Unsplash

Setup do projeto

Este projeto foi migrado da versão 2.2 para o dotnet core 3.1. Para conferir como criar o projeto do zero consulte a parte 1 deste tutorial. Sobre pacotes nuget, o pacote graphiql foi atualizado e foram adicionados os pacotes Microsoft.AspNetCore.Mvc.NewtonsoftJson e Newtonsoft.Json.

Pacotes nuget da api

Na migração para a versão 3.1 a classe Startup.cs sofreu alterações no método ConfigureServices. Foi removido o uso de endpoints através do MVC e configurado NewtonsoftJson como serializador de resposta.

Mutations

Para iniciar, vamos criar uma forma de informar os valores de entrada da mutation. Este deve ser uma classe do tipo InputObjectGraphType. No nosso caso vamos criar a classe UsuarioInputType.

Agora vamos criar nossa primeira mutação 🎉.

Criar usuário

Seguindo o CRUD a primeira mutação será a criarUsuario. Nela iremos usar UsuarioInputType como variavel de entrada e para confirmar a criação do registro será retornado UsuarioType.

Para a mutation ser reconhecida precisamos adiciona-la na classe schema da API.

Agora podemos testar nossa implementação. Para testar, informamos a mutation criarUsuario no campo query e objeto usuário nas variáveis da query.

Mutation criarUsuario

Alterar usuário

Vamos agora criar uma mutation para alterar dados do usuário. Neste método é comum passar dois valores de Input, sendo um deles o objeto com os valores para alteração e outro o id do objeto a ser alterado.

Para testar esta mutation de alteração de dados do usuário podemos aplicar a query como na imagem a seguir.

Mutation alterarUsuario

Remover usuário

Bora pra ultima mutation, remover usuário. Nesta podemos informar como parametro de Input o id do usuário que queremos remover da base.

Abaixo segue o teste feito na interface do graphiql. Na implementação feita podemos receber como feedback a mensagem de sucesso do usuário removido ou de exceção do usuário inexistente.

Mutation removerUsuario

Exceções e soluções

Durante a migração do projeto para versão 3 do dotnet e a criação de mutations me deparei com alguns cenários com exceções que tomaram tempo até a solução deles. Faz parte da vida de desenvolvedor não eh mesmo? 😊 Abaixo deixo uma sequencia de exceções e soluções aplicadas.

Exceção 1: {“Endpoint Routing does not support ‘IApplicationBuilder.UseMvc(…)’. To use ‘IApplicationBuilder.UseMvc’ set ‘MvcOptions.EnableEndpointRouting = false’ inside ‘ConfigureServices(…).”}

Solução 1: Na versão 2 o gerenciamento de rotas era mais automatizado. Porem agora é necessário explicitar a forma que você deseja gerenciar as rotas. Em ConfigureServices da classe Startup adicione configuração AddMvc(option => option.EnableEndpointRouting = false).

Exceção 2: The JSON value could not be converted to newtonsoft.json.linq.jtoken

Solução 2: Em ConfigureServices adicionar instrução AddNewtonsoftJson junto da configuração de mvc AddMvc

services.
AddMvc(option => option.EnableEndpointRouting = false)
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
.AddNewtonsoftJson(opt => opt.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);`

Exceção 3: Variable \”$usuario\” of type \”UsuarioInput!\” used in position expecting type \”Usuario!\”.

Solução 3: Isto ocorre geralmente quando o Type configurado no query arguments não é valido para uso na mutation. O query argument para mutation deve ser do tipo InputObjectGraphType. No erro acima o utilizado é do tipo ObjectGraphType.Por exemplo dentro da class BlogMutation:

Field<UsuarioType>("criarUsuario",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<UsuarioType>> { Name = "usuario" }),
resolve: context => {
var usuario = context.GetArgument<Usuario>("usuario");
return repositorio.Adicionar(usuario);
});

E para corrigir informamos UsuarioInputType no lugar de UsuarioType nos argumentos da mutation criarUsuario:

Field<UsuarioType>("criarUsuario",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<UsuarioInputType>> { Name = "usuario" }),
resolve: context =>
{
var usuario = context.GetArgument<Usuario>("usuario");
return repositorio.Adicionar(usuario);
});

Então é isso galera. Espero que o conteúdo possa auxiliar na construção de sua API com GraphQL. Até a próxima.

--

--

Jozimar Back

I write articles about my experience in Data Engineering.