ASP.net Core APP 05 – Construção de APIs RESTful com ASP.net Core

O objetivo desta etapa é concluir o desenvolvimento da API RESTful de produtos criando todos o métodos padrões que compõe uma API. Importante destacar que este material foi baseado na documentação oficial da Microsoft disponível em: https://docs.microsoft.com/pt-br/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.0&tabs=visual-studio

Mas antes de iniciar o desenvolvimento da API em si, vamos modificar o código das nossas classes de serviço para que o endereço de conexão com o servidor mongo fique dentro do arquivo de configuração da aplicação. Para isso vamos criar uma nova classe chamada MongoConfiguration, essa classe vai possuir um atributo chamado connection.

namespace myshop.Services
{
    public class MongoConfiguration
    {
        public string Connection { get; set; }
    }
}

Agora vamos modificar o arquivo appsettings.json para incluir uma nova sessão contendo a string de conexão do servidor Mongo.

"MongoConfiguration":{
    "Connection" : "mongodb://localhost:27017",
    "ConnectionUNIVILLE" : "mongodb://172.18.0.35:27017"
  },

Em seguida vamos modificar a classe Startup.cs para que no método de configuração do serviço o dados da nova sessão de configuração do banco Mongo sejam carregados para a instância da classe MongoConfiguration e que ela seja inserida como um Singleton nas classes de serviço.

var mongoConfiguration = new MongoConfiguration();
            new ConfigureFromConfigurationOptions<MongoConfiguration>(
                Configuration.GetSection("MongoConfiguration"))
                    .Configure(mongoConfiguration);
            services.AddSingleton(mongoConfiguration);

Em seguida podemos modificar as classes UserService e ProductService para que no construtor recebam a instância da classe MongoConfiguration e utilizem a string de conexão.

public UserService([FromServices]MongoConfiguration mongoConfiguration)
        {
            con = new MongoClient(mongoConfiguration.Connection);
            db = con.GetDatabase("dbwalter");
            if(db.GetCollection<User>("Users") == null)
                db.CreateCollection("Users");
        }
public ProductService([FromServices]MongoConfiguration mongoConfiguration)
        {
            con = new MongoClient(mongoConfiguration.Connection);
            db = con.GetDatabase("dbwalter");
            if(db.GetCollection<Product>("Products") == null)
                db.CreateCollection("Products");
        }

Método GET

Resolvida esta pendência vamos focar na API de produtos, o primeiro método que vamos implementar é a busca de um produto pelo ID. Para isso vamos modificar nossa interface IProductService criando um novo método GetById(String id)

Product GetById(string id);

A implementação deste método fará uma consulta na coleção de produtos para retornar o item que possuir o id igual ao recebido por parâmetro.

public Product GetById(string id)
        {
            var collection = db.GetCollection<Product>("Products");
            return collection.Find<Product>(p => p.Id == id).FirstOrDefault();
        }

Por fim podemos implementar o método na API controller chamada GetById, anotando com o decorador [HttpGet(“{id}”)] indicando que o método receberá o ID pela URL.

Para fazer a chamada deste método é necessário antes chamar o endereço de login https://localhost:5001/api/login para receber o token JWT.

Método POST

O próximo método a ser implementado é o POST que receberá uma nova instância da classe Produto para ser inserida no banco. Para isso vamos modificar um pouco o código do nosso IProductService para que a assinatura do método save retorne a instância da classe que foi inserida no banco.

Product save(Product product);

Em seguida vamos modificar o código do método save na classe ProductService para retornar a instância da classe Product.

public Product save(Product product)
        {
            var collection = db.GetCollection<Product>("Products");
            if(product.Id == null | product.Id == String.Empty)
                collection.InsertOne(product);
            else{
                var filter = Builders<Product>.Filter.Eq("Id", product.Id);
                var updateDefinition = Builders<Product>.Update
                        .Set(p => p.Name, product.Name)
                        .Set(p => p.Description, product.Description)
                        .Set(p => p.Price, product.Price);
                collection.UpdateOne(filter,updateDefinition);
            }
            return product;
        }

Podemos agora modificara classe ProductAPIController para incluir o novo método PostProduct que receberá a instância do objeto product e chamará o método save do serviço.

[HttpPost]
        public Product PostProduct([FromBody]Product product){
            return productService.save(product);
        }

Para testar o novo método vamos configurar a ferramenta Postman para o método POST a URL https://localhost:5001/api/product informando o token JWT na opção de autorization e no body passando um objeto JSON contendo os campos do objeto.

Método PUT

O método PUT é utilizado para atualizar um objeto, por isso sua implementação se torna mais simples pois nosso método save do serviço já realiza essa ação. Por isso basta alterar a classe ProductAPIController conforme exemplo abaixo.

[HttpPut("{id}")]
        public Product PutProduct(string id, [FromBody]Product product){
            if (!id.Equals(product.Id))
            {
                return null;
            }
            return productService.save(product);
        }

Para realizar o teste devemos utilizar o método PUT na URL https://localhost:5001/api/product/IDDOOBJETOPARAALTERACAO passando o token JWT e no body o objeto contendo os novos valores.

Método DELETE

O último método para concluir nossa API é o DELETE, para isso vamos modificar nossa classe de serviço para criar um novo método delete(string id)

void delete(string id);

Agora vamos implementá-lo em nossa classe de serviço.

public void delete(string id)
        {
            var collection = db.GetCollection<Product>("Products");
            collection.DeleteOne<Product>(p => p.Id == id);
        }

Para concluir vamos modificar nossa classe ProductAPIController para criar este novo método com o decoretor HttpDelete.

O teste do método deve utilizar o verbo Delete, a URL https://localhost:5001/api/product/IDDOOBJETOPARAEXCLUSAO deve ser passado o token JWT.