Facebook Pixel
Criando Endpoints REST API com C#, Visual Studio e .NET Core – HTTP Post, Get e Delete

Criando Endpoints REST API com C#, Visual Studio e .NET Core – HTTP Post, Get e Delete

Este artigo é parte da série:

Dando continuidade ao processo de criação da nossa REST API, agora vamos ajustar todos os parâmetros de entrada e saída.

Para fins deste exemplo, vamos trabalhar com uma lista em memória, A lista de UFs e capitais feitas no artigo anteror, mas dessa vez, vamos colocar a montagem da lista no construtor da classe para que possamos fazer outros métodos que manipulem a mesma lista.

Na linguagem C#, para escrever um construtor basta fazer um método com o mesmo nome da classe. Como em nosso exemplo, a classe se chama ListaUFController, então se faz necessário criar um método com este mesmo nome. Este método será executado todas as vezes que o objeto for instanciado. Sendo assim, agora o início da nossa classe vai ficar assim:

public class ListaUFController : ControllerBase
{

    static List<UF> UFs = new List<UF>();

    public ListaUFController()
    {
        if (UFs.Count == 0)
        {
            UFs.Add(new UF { Id = 1, Nome = "RJ", Capital = "Rio de Janeiro" });
            UFs.Add(new UF { Id = 2, Nome = "SP", Capital = "São Paulo" });
            UFs.Add(new UF { Id = 3, Nome = "BA", Capital = "Salvador" });
        }
    }

Com isso criamos um objeto UFs que é uma lista de objetos UF, depois, no construtor, verificamos se a lista já foi populada e, caso não tenha sido, ela passa a ser populada com as UFs RJ, SP e BA. Se a montagem desta lista estivesse fora do if, a cada vez que o objeto fosse instanciado a lista de UFs ganharia mais 3 elementos.

A nova versão da classe ficou assim:

using Microsoft.AspNetCore.Mvc;
using Treino_REST_02.Models;

namespace Treino_REST_02.Controllers
{
    [Route("api/Operacao")]
    [ApiController]
    public class SomaController : ControllerBase
    {

        [HttpPost(Name = "Soma")]
        public int Soma(int A, int B) 
        {
            return A + B;
        }

    }

    [Route("api/ListaUF")]
    [ApiController]
    public class ListaUFController : ControllerBase
    {

        static List<UF> UFs = new List<UF>();
    
        public ListaUFController()
        {
            if (UFs.Count == 0)
            {
                UFs.Add(new UF { Id = 1, Nome = "RJ", Capital = "Rio de Janeiro" });
                UFs.Add(new UF { Id = 2, Nome = "SP", Capital = "São Paulo" });
                UFs.Add(new UF { Id = 3, Nome = "BA", Capital = "Salvador" });
            }
        }

        [HttpGet(Name = "Listagem")]
        public IEnumerable<UF> ListaUF()
        {
            return UFs;
        }

        [HttpGet("{IdUF:int}", Name = "MostraUF")]
        public UF MostraUF(int IdUF)
        {
            UF result = UFs.Find(x => x.Id == IdUF);
            return result;
        }

        [HttpPost(Name ="Adiciona")]
        public IEnumerable<UF> AdicionaUF(UF NovaUF)
        {
            UFs.Add(NovaUF);
            return UFs;
        }

        [HttpDelete(Name ="EliminaUF")]
        public IEnumerable<UF> EliminaUF(int DelId)
        {
            UF result = UFs.Find(x => x.Id == DelId);
            UFs.Remove(result);
            return UFs;
        }
    }
}

Agora temos os três verbos mais usados em uma REST API em ação: get, post e delete.

  • O método ListaUF continua trazendo a relação de UFs e possui o verbo get, que deve ser utilizado quando o método retorna uma consulta sem fazer alterações na camada de persistência.
  • O método MostraUF mostra os dados de uma única UF fazendo a pesquisa por id. Como se trata de uma consulta, utiliza o verbo get.
  • O método Adiciona UF acrescenta uma nova UF à lista e possui o verbo post, que deve ser utilizado quando o método faz alterações na camada de persistência, como inclusões e alterações em bancos de dados.
  • O método EliminaUF elimina uma das UFs da lista e utiliza o método delete, que deve ser utilizado quando a operação irá resultar em eliminação de itens na camada de persistência.

Execute o programa e veja os 3 métodos funcionando. É agora que começa nossa aventura de hoje.

Execute qualquer um dos métodos dentro do Swagger e observe que não importa o que aconteça, o nosso retorno sempre é do tipo 200 (Ok). Na verdade, se você olhar mais abaixo, nos tipos de retorno do dos nossos métodos, só temos o tipo 200.

Existe um tipo chamdo ActionResult específico para trabalhar com REST API, e nele podemos especificar os tipos de retorno. Por exemplo, digamos que o usuário entrou com um id inválido no método MostraUF, é interessante que a API entregue o tipo 404 (Not Found) como resposta. Para isso, vamos fazer a seguinte modificação:

        [HttpGet("{IdUF:int}", Name = "MostraUF")]
        public ActionResult<UF> MostraUF(int IdUF)
        {
            UF result = UFs.Find(x => x.Id == IdUF);
            if (IdUF == 0)
            {
                return BadRequest();
            }
            if (result == null)
            {
                return NotFound();
            }
            return Ok(result);
        }

Agora execute o Swagger novamente, execute o método MostraUF e faça dois testes: no primeiro digita uma id válida, entre 1 e 3 e veja a resposta, depois digite uma id inválida e observe o código de erro 404 sendo entregue como resposta. Faça o teste também entrando com zero no id e veja a resposta BadRequest.

Apesar de estar tudo funcionando dentro do planejado, observe que logo abaixo do código 404 existe uma palavra “Undocumented”, e que na lista de “resposes” lá no final só consta 200 Ok. Agora vamos informar ao Swagger sobre as possibilidades de retorno. Para isso, faça a seguinte modificação:

        [HttpGet("{IdUF:int}", Name = "MostraUF")]
        [ProducesResponseType(200)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult<UF> MostraUF(int IdUF)
        {
            if (IdUF == 0)
            {
                return BadRequest();
            }
            UF result = UFs.Find(x => x.Id == IdUF);
            if (result == null)
            {
                return NotFound();
            }
            return Ok(result);
        }

Agora o Swagger vai te mostrar que todos os tipos de retorno estão documentados.

E assim ficou o nosso código ao final deste exercício:

using Microsoft.AspNetCore.Mvc;
using Treino_REST_02.Models;

namespace Treino_REST_02.Controllers
{
    [Route("api/Operacao")]
    [ApiController]
    public class SomaController : ControllerBase
    {

        [HttpPost(Name = "Soma")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public ActionResult<int> Soma(int A, int B) 
        {
            return Ok(A + B);
        }

    }

    [Route("api/ListaUF")]
    [ApiController]
    public class ListaUFController : ControllerBase
    {

        static List<UF> UFs = new List<UF>();
    
        public ListaUFController()
        {
            if (UFs.Count == 0)
            {
                UFs.Add(new UF { Id = 1, Nome = "RJ", Capital = "Rio de Janeiro" });
                UFs.Add(new UF { Id = 2, Nome = "SP", Capital = "São Paulo" });
                UFs.Add(new UF { Id = 3, Nome = "BA", Capital = "Salvador" });
            }
        }

        [HttpGet(Name = "Listagem")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public ActionResult<IEnumerable<UF>> ListaUF()
        {
            return Ok(UFs);
        }

        [HttpGet("{IdUF:int}", Name = "MostraUF")]
        [ProducesResponseType(200)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult<UF> MostraUF(int IdUF)
        {
            if (IdUF == 0)
            {
                return BadRequest();
            }
            UF result = UFs.Find(x => x.Id == IdUF);
            if (result == null)
            {
                return NotFound();
            }
            return Ok(result);
        }

        [HttpPost(Name ="Adiciona")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public ActionResult<IEnumerable<UF>> AdicionaUF(UF NovaUF)
        {
            UFs.Add(NovaUF);
            return Ok(UFs);
        }

        [HttpDelete(Name ="EliminaUF")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult<IEnumerable<UF>> EliminaUF(int DelId)
        {
            if (DelId == 0)
            {
                return BadRequest();
            }
            UF result = UFs.Find(x => x.Id == DelId);
            if (result == null)
            {
                return NotFound();
            }
            UFs.Remove(result);
            return Ok(UFs);
        }
    }
}

Próximo:

Deixe seu comentário