ASP .NET Core - Usando GraphQL - II


  Neste artigo vou apresentar o GraphQL e mostrar como podemos usá-lo em uma aplicação ASP .NET Core.

Continuando a primeira parte do artigo veremos agora como implementar o GraphQL em nosso projeto ASP .NET Core.

Integração do GraphQL com a ASP .NET Core

Desde que o suporte ao GraphQL não é fornecido diretamente pela ASP .NET Core temos que instalar algumas bibliotecas para dar esse suporte via pacote Nuget:

1- Biblioteca GraphQL

2- Biblioteca GraphQL.Server.Transports.AspnetCore - permite obter o GraphQL como uma dependência .NET

3- Biblioteca GraphQL.Server.Ui.Playground -  permite enviar consultas GraphQL para o servidor

Todos os pacotes também podem ser instalados via janela do Package Manager Console usando o comando:
Install-Package <nome_do_pacote>

Após instalar esses pacotes nosso ambiente esta preparado para usar os recursos do GraphQL e vamos realizar a lógica da integração com a ASP .NET Core a seguir.

Criando Objetos GraphQL : Type, Query e Schema

Vamos criar uma nova pasta no projeto chamada GraphQL e dentro desta pasta vamos criar a pasta GraphQLScheme onde vamos criar a classe AppScheme.cs :

using GraphQL;
using GraphQL.Types;
namespace Aspncore_GraphQL.GraphQL.GraphQLScheme
{
    public class AppScheme : Schema
    {
        public AppScheme(IDependencyResolver resolver) : base(resolver)
        {
        }
    }
}

Esta classe herda de Schema que reside no namespace GraphQL.Types. No construtor da classe injetamos a interface IDependencyResolver que vai nos ajudar a resolver os nossos objetos Query, Mutation ou Subscriptions.

Cada uma dessas propriedades do Schema implementa IObjectGraphType o que significa que os objetos que vamos resolver precisam implementar o mesmo tipo.

Além disso nossa API GraphQL não pode retornar nosso modelo diretamente como um resultado mas vai retornar tipos GraphQL que implementam IObjectGraphType.

Vamos agora criar uma nova pasta chamada GraphQLType dentro da pasta GraphQL e nesta pasta vamos criar a classe CategoriaType.cs

using Aspncore_GraphQL.Entities;
using GraphQL.Types;
namespace Aspncore_GraphQL.GraphQL.GraphQLTypes
{
    public class CategoriaType : ObjectGraphType<Categoria>
    {
        public CategoriaType()
        {
            Field(x => x.CategoriaId, type: typeof(IdGraphType))
                .Description("Propriedade CategoriaId do objeto categoria.");
            Field(x => x.Nome)
                .Description("Propriedade Nome do objeto categoria.");
            Field(x => x.ImagemUrl)
                .Description("Propriedade ImagemUrl do objeto categoria.");
        }
    }
}

Esta classe CategoriaType foi usada para substituir o modelo Categoria dentro da API GraphQL. Esta classe herda da classe genérica  ObjectGraphType<> a qual implementa a interface IObjectGraphType.

No método Field especificamos os campos que representam nossas propriedades para a classe de modelo Categoria.

Agora vamos criar dentra da pasta GraphQL a pasta GraphQLQueries e nesta pasta a classe AppQuery :

using Aspncore_GraphQL.Contracts;
using Aspncore_GraphQL.GraphQL.GraphQLTypes;
using GraphQL.Types;
namespace Aspncore_GraphQL.GraphQL.GraphQLQueries
{
    public class AppQuery : ObjectGraphType
    {
        public AppQuery(ICategoriaRepository repository)
        {
            Field<ListGraphType<CategoriaType>>(
               "categorias",
               resolve: context => repository.GetAll()
           );
        }
    }
}

A classe AppQuery também herda de ObjectGraphType. Também injetamos nosso objeto de repositório dentro do construtor e criamos um campo para retornar o resultado para a consulta específica.

Nesta classe, usamos a versão genérica do método Field, que aceita algum tipo "tipo" como um parâmetro genérico.

Esta é a representação GraphQL.NET para os tipos normais do .NET. Então, ListGraphType é a representação do tipo List e, temos IntGraphType, StringGraphType, etc. (Para a lista completa, visite SchemaTypes no GraphQL .NET.)

O parâmetro "categorias" é um nome de campo (a consulta do cliente deve corresponder a esse nome) e o segundo parâmetro é o próprio resultado.

Agora temos que modificar nossa classe AppSchema:

using Aspncore_GraphQL.GraphQL.GraphQLQueries;
using GraphQL;
using GraphQL.Types;
namespace Aspncore_GraphQL.GraphQL.GraphQLScheme
{
    public class AppScheme : Schema
    {
        public AppScheme(IDependencyResolver resolver) : base(resolver)
        {
            Query = resolver.Resolve<AppQuery>();
        }
    }
}

Incluimos a linha de código que resolve a nossa consulta definida em AppQuery.

Registrando as bibliotecas e o Schema

Vamos agora fazer o registro das bibliotecas e do Schema nos métodos da classe Startup.

1- No método ConfigureServices:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<AppDbContext>();
            services.AddScoped<ICategoriaRepository, CategoriaRepository>();
            services.AddScoped<IProdutoRepository, ProdutoRepository>();
            services.AddScoped<IDependencyResolver>(s => 
                      new FuncDependencyResolver(s.GetRequiredService));
            services.AddScoped<AppScheme>();
            services.AddGraphQL(o => { o.ExposeExceptions = false; })
                .AddGraphTypes(ServiceLifetime.Scoped);
            services.AddControllers()
                .AddNewtonsoftJson();
        }

2- No método Configure:

       public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseGraphQL<AppScheme>();
            app.UseGraphQLPlayground(options: new GraphQLPlaygroundOptions());
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

No método ConfigureServices, registramos o DependencyResolver (para nossas consultas) e a classe AppScheme também.

Registramos o GraphQL com o método AddGraphQL e registramos todos os tipos GraphQL (classes Query e Type) com o método AddGraphTypes. Sem esse método, teríamos que registrar todos os tipos e consultas manualmente em nossa API.

Por fim, no método Configure, estamos adicionando nosso esquema ao pipeline do request, bem como a ferramenta de interface do Playground que estamos prestes a usar.

A estrutura final do projeto ficou assim:

Testando o GraphQL na ASP .NET Core

Para poder fazer o teste e verificar se a integração do GraphQL ao ASP .NET Core esta funcionando temos que usar a ferramenta GraphQL.UI.Playouground.

Vamos inciar nossa aplicação e então navegar para : https://localhost:5001/ui/playground

Vamos enviar a seguinte consulta no formato JSON:

{
   categorias {
      categoriaid,
      nome,
      imagemurl
   }
}

Teremos o resultado da consulta exibida.

Concluímos assim a criação e a configuração da aplicação ASP .NET Core a seguir vamos implementar o GraphQL em nossa aplicação.

"A luz semeia-se para o justo, e a alegria para os retos de coração."
Salmos 97:11

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ?

Referências:


José Carlos Macoratti