Requisições em C#
Tags: csharp, dotnet, programming, tutorial
Published: 2022-11-06 22:13:38

### 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/**](https://pokeapi.co/)

[](https://pokeapi.co/api/v2/pokemon?limit=9&offset=0)

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:

```json
{
  "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/"
    }
  ]
}
```

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](https://app.quicktype.io/)

então vamos criar a classe **Pokemon**

```csharp
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; }
	}
}
```

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. 

```csharp
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; }
		}	
	}
}
```

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. 

```csharp
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);
		}
	}
}
```

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.
> 

```csharp
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; }
        }
    }
}
```

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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pvfo1fgkvswwg8iqcrad.png)

### ViaCep

Outro exemplo de API que podemos utilizar é a API do: [https://viacep.com.br/](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. 

```csharp
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;}
}
```

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.