DEV Community

Cover image for Requisições em C#
Eduardo Ribeiro
Eduardo Ribeiro

Posted on

Requisições em C#

PokeAPI

Como sabemos o C# é orientado a objetos, com essa premissa tudo é feito com uso de classes, que possuem seus métodos e atributos, quando queremos fazer uma requisição Http a algum endpoint de uma API qualquer, temos que ter em mente que ela irá nos retornar na grande maioria das vezes um json, que a gente precisa converter em um objeto, geralmente usando a biblioteca NewtonSoft. Porém apenas fazendo essa conversão para um tipo de objeto qualquer “genérico”, nós não conseguimos acessar por exemplo os campos da requisição exemplo: pokemon.nome, para ter acesso nós precisamos criar uma classe que tem como atributos os campos que a gente irá receber de retorno da nossa requisição. Vamos levar em consideração que queremos utilizar a API de Pokémon: https://pokeapi.co/

se a gente acessar o link acima iremos receber um json com os 3 pokémons da primeira geração, e suas respectivas evoluções:

{
  "count": 1154,
  "next": "https://pokeapi.co/api/v2/pokemon?offset=9&limit=9",
  "previous": null,
  "results": [
    {
      "name": "bulbasaur",
      "url": "https://pokeapi.co/api/v2/pokemon/1/"
    },
    {
      "name": "ivysaur",
      "url": "https://pokeapi.co/api/v2/pokemon/2/"
    },
    {
      "name": "venusaur",
      "url": "https://pokeapi.co/api/v2/pokemon/3/"
    },
    {
      "name": "charmander",
      "url": "https://pokeapi.co/api/v2/pokemon/4/"
    },
    {
      "name": "charmeleon",
      "url": "https://pokeapi.co/api/v2/pokemon/5/"
    },
    {
      "name": "charizard",
      "url": "https://pokeapi.co/api/v2/pokemon/6/"
    },
    {
      "name": "squirtle",
      "url": "https://pokeapi.co/api/v2/pokemon/7/"
    },
    {
      "name": "wartortle",
      "url": "https://pokeapi.co/api/v2/pokemon/8/"
    },
    {
      "name": "blastoise",
      "url": "https://pokeapi.co/api/v2/pokemon/9/"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Como mencionei anteriormente, temos que criar uma ou mais classe onde os parâmetros serão os campos da requisição. Existe um site que ajuda bastante:

Instantly parse JSON in any language | quicktype

então vamos criar a classe Pokemon

namespace ConsumoAPI
{
    internal class Pokemon 
    {
                [JsonProperty("count")]
        public long Count { get; set; }

        [JsonProperty("next")]
        public object Next { get; set; }

        [JsonProperty("previouns")]
        public object Previous { get; set; }

        [JsonProperty("results")]
        public List<Result> Results { get; set; }
    }
}
Enter fullscreen mode Exit fullscreen mode

Esses são os atributos da classe, utilizando o JsonProperty, estamos dizendo para o C# que o atributo X é um dado Y que vem de um campo Json

Podemos perceber que em Result nós tempos uma lista, mas que lista é essa? essa lista é um campo que vem em formato de Array/List dentro da requisição. Mas afinal é uma lista de que? o que tem dentro dela? para mostrar para o C# isso, nos temos que criar uma classe do tipo Result para o c# entender que essa lista é de um determinado tipo, e esse tipo é o ripo Result utilizei esse nome pois, é o nome do campo que vem. como podemos ver no Json, vem um array de objetos “pokémons” chamado results.

namespace ConsumoAPI
{
    internal class Pokemon 
    {
        [JsonProperty("count")]
    public long Count { get; set; }

    [JsonProperty("next")]
      public object Next { get; set; }

        [JsonProperty("previouns")]
    public object Previous { get; set; }

      [JsonProperty("results")]
    public List<Result> Results { get; set; }

        // Partial é considerado uma classe que faz parte de uma outra classe "Eu acho"
        public partial class Result
        {
             [JsonProperty("name")]
       public string Name { get; set; }

       [JsonProperty("url")]
       public Uri Url { get; set; }
        }   
    }
}
Enter fullscreen mode Exit fullscreen mode

bom, agora que temos a classe no formato do retorno da requisição, precisamos criar um metodo, em que iremos fazer a requisição, mas existe algumas ressalvas, para que nós possamos acessar esse metodo no nosso programa, na classe principal sem ter que criar um objeto da nossa classe, então iremos criar um metodo statico que será assíncrono, pois precisamos esperar o retorno da requisição, e como sabemos leva um pequeno tempo, até a requisição chegar no servidor e ele nos retornar os dados, e também esse metodo será do tipo Task, que informa para o C# que é uma tarefa que vai ser executada em outra Thread, mas não precisamos nos preocupar com isso por agora.

public static async GetALLPokemons(){
    Uri url = new Uri("https://pokeapi.co/api/v2/pokemon?limit=151&offset=0");
    Httpclient client = new HttpClient();
    //aqui fazempos a requisição do tipo get asyncrona
    var response = await client.GetAsync(url);
    if(response.IsSuccessStatusCode){
        var result = await response.Content.ReadAsStringAsync();

        /* 
            aqui dizemos que a variável lista é do tipo POKEMON e ela vai receber
            o resultado da deserilzação, meio que ele vai converter o Json que recebemos
            em um objeto, e depois irá atribuir os campos desse Json a um objeto 
         */ 
        var listaDePokemon = JsonConvert.DeserializeObject<Pokemon>(result);

        //para cada pokemon na lista de pokemon ele irá mostrar o nome e a url
        foreach(var poke in listaDePokemon.Results)
        {
            Console.WriteLine("\n--------------------------------------------------\n" + 
            "Nome: " + poke.Name + "\n" +
      "Url: " + poke.Url);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Pronto agora só precisamos ir no nosso programa principal e utilizar o metodo, mas lembrando que para utilizar o await para esperar a resposta tempos que falar que nossa função superior a que a gente esta colocando o await dentro, tempos que dizer que ela é async e também do tipo Task.

Abaixo o código está junto, no mesmo arquivo, porém podem está sim em arquivos separados, coloquei elas juntas, pois fica mais fácil de visualizar aqui no notion.

namespace ConsumoAPI
{
//classe do programa principal
    class Program
    {
        static async Task Main(String[] args)
        {
            await Pokemon.GetAllPokemon();
        }
    }

//classe pokemon
    internal class Pokemon
    {
        [JsonProperty("count")]
        public long Count { get; set; }

        [JsonProperty("next")]
        public object Next { get; set; }

        [JsonProperty("previouns")]
        public object Previous { get; set; }

        [JsonProperty("results")]
        public List<Result> Results { get; set; }

        //metodos
        public static async Task GetAllPokemons()
        {
            Uri url = new Uri("https://pokeapi.co/api/v2/pokemon?limit=151&offset=0");

            HttpClient client = new HttpClient();
            var response = await client.GetAsync(url);
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync();

                var listaPokemon = JsonConvert.DeserializeObject<Pokemon>(result);

                foreach(var poke in listaPokemon.Results)
                {
                    Console.WriteLine("\n--------------------------------------------------\n" +
                        "Nome: " + poke.Name + "\n" +
                        "Url: " + poke.Url);

                }


            }

        }

        public partial class Result
        {
            [JsonProperty("name")]
            public string Name { get; set; }

            [JsonProperty("url")]
            public Uri Url { get; set; }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Quando executarmos o programa teremos o retorno esperado no nosso console:

Image description

ViaCep

Outro exemplo de API que podemos utilizar é a API do: https://viacep.com.br/ onde a gente passa um código e ela nos retorna os dados de um determinado lugar. Neste exemplo eu não irei dar tantos detalhes do código, pois é basicamente igual ao código anterior, precisamos de uma classe que deve ter os mesmos parâmetros que os campos que vem no Json da requisição, um método que faz a requisição.

internal class ViaCep
    {

        public static async Task GetCity(string cep)
        {
            Uri url = new Uri("https://viacep.com.br/ws/"+ cep +"/json/");
            HttpClient client = new HttpClient();
            try
            {
                var response = await client.GetAsync(url);
                var content = await response.Content.ReadAsStringAsync();

                var cidade = JsonConvert.DeserializeObject<Cidade>(content);

                Console.WriteLine(cidade.Localidade);

            }catch(Exception e)
            {
                Console.WriteLine(e);
            }

        }
    }

    public partial class Cidade
    {
       public string? Cep { get; set; }
       public string? Logadouro { get; set; }
       public string? Complemento { get; set; }
       public string? Localidade { get; set; }
       public string? Bairro { get; set; }
       public string? Uf { get; set; }
       public string? Ibge { get; set;}
       public string? Gia { get; set;}
       public string? Ddd { get; set;}
       public string? Siafi { get; set;}
}
Enter fullscreen mode Exit fullscreen mode

Só que no exemplo acima, nós recebemos o cep como parâmetro, ai na função Main quando chamamos o metodo estático GetCity, nós passamos uma string como parâmetro.

Latest comments (0)