Criando e executando endpoints

Neste capítulo, vamos escrever o nosso primeiro endpoint. Iremos trabalhar somente no arquivo Biblioteca/Program.cs. Nosso objetivo por enquanto é escrever um endpoint, e testar se ele responde corretamente.

Iniciando o serviço Web

Para começar, abra Biblioteca/Program.cs, e apague todas as linhas. Vamos escrever nós mesmos somente as linhas necessárias para iniciar um serviço.

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.Run();

Estas são as chamadas de função essenciais para que a sua aplicação aja como uma API Web - ou seja, para que ela inicie e comece a escutar requisições HTTP em uma porta (definida em launchSettings.json). Nenhuma outra configuração adicional foi realizada, nem nenhum endpoint foi definido. Sua aplicação apenas inicia e fica escutando na porta correspondente.

Tente executar o projeto através do depurador. Você deve se lembrar do arquivo launchSettings.json que vimos no capítulo anterior. Nele é configurado a porta em que nossa aplicação escutará as requisições, definido em uma configuração semelhante a http://localhost:<numero> (por exemplo, http://localhost:5000). Este número após o sinal de dois-pontos é a porta que sua aplicação estará escutando.

Abra uma nova aba no seu navegador de internet, e, na barra de endereço, escreva http://localhost:<porta>, onde <porta> é o número que está definido no seu launchSettings.json (no meu caso, este número é 5000, portanto o endereço que eu devo digitar é http://localhost:5000. Você pode alterar o seu launchSettings.json para que a sua porta também seja 5000, ou qualquer outro número que desejar). Se tudo der certo - ou seja, sua aplicação está sendo executada, e a porta que você escreveu no navegador é a correta - você verá uma janela vazia. Isto significa que o navegador conseguiu acessar o endereço que você escreveu, só que, como não definimos nenhum endpoint, nossa aplicação não devolveu nada para o navegador.

Se você não está executando o projeto, ou escreveu a porta errada, você provavelmente verá uma mensagem no navegador semelhante a esta:

Ou esta, onde digitei uma porta aleatória:

Criando o primeiro endpoint

Se você conseguiu executar o projeto, acessar o seu endereço via navegador, e ver uma aba vazia sem nenhuma mensagem de erro, então tudo está pronto para que possamos criar nosso primeiro endpoint.

Vamos escrever um de teste, apenas. Modifique o seu Program.cs para que ele fique desta forma:

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/", () =>
{
    return "Olá, mundo!";
});

app.Run();

Note que adicionamos o seguinte trecho de código:

app.MapGet("/", () =>
{
    return "Olá, mundo!";
});

app é uma instância de WebApplication e é neste objeto que podemos configurar nossa API, além de adicionar quais os endpoints ela irá reponder. Neste caso, adicionamos um endpoint através do método MapGet(string, Delegate), que fará com que ela responda ao verbo GET no caminho / (ou seja, a raíz), com uma mensagem simples.

Acesse a URL da sua aplicação no navegador novamente, como fizemos anteriormente (no meu caso, http://localhost:5000). Você deverá ver a mensagem que você escreveu.

Vamos fazer nosso endpoint ficar um pouco mais inteligente e responder com mensagens aleatórias. Altere o seu endpoint para que ele fique desta forma:

app.MapGet("/", () =>
{
    string[] saudacoes = ["Olá!", "こんにちは", "Привет", "Ողջույն"];

    return saudacoes[Random.Shared.Next(saudacoes.Length)];
});

Agora, o endpoint irá obter uma mensagem de saudação aleatória a cada vez que você fizer uma nova requisição. Experimente atualizar a página com o endereço da sua aplicação algumas vezes.

Estrutura de uma requisição HTTP

Quando você acessa essa URL no seu navegador (no caso deste exemplo, http://localhost:5000), uma mensagem HTTP é preparada e enviada para o endereço especificado.

HTTP é um acrônimo para Hypertext Transfer Protocol, que é um protocolo para troca de mensagens entre nós em uma rede em uma arquitetura cliente-servidor.

Este protocolo define um padrão para que um cliente tenha acesso a um recurso disponibilizado por um servidor. Por exemplo, quando você acessa uma página Web, seu navegador, o cliente, solicita a página que você deseja ver para o servidor da aplicação.

Esta solicitação ocorre através de uma troca de mensagens entre o cliente e o servidor. O cliente envia uma mensagem de solicitação, e o servidor devolve uma mensagem de resposta. Estas mensagem possuem uma estrutura composta por um verbo, um identificador de recurso, cabeçalhos, e, opcionalmente, um conteúdo. Além disso, toda resposta a uma mensagem enviada por um cliente possui também um código de status.

O identificador do recurso (ou URI) é o nome que identifica o recurso que o cliente deseja acessar. Em uma URL de um site, a URI é todo o conteúdo que aparece depois do primeiro /. Por exemplo, na url https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs, a parte que corresponde à URI é /wiki/Plan_9_from_Bell_Labs. Se não há nada após a barra, então a URI é apenas /.

O verbo (ou método) determina a ação que o cliente deseja realizar sobre o recurso. Por exemplo, GET, por padrão, significa que o cliente deseja ler aquele recurso; já o POST, por sua vez, significa que o cliente deseja escrever naquele recurso.

Imagine que você está realizando um cadastro em algum site. Você preenche os seus dados em um formulário e os envia. O site completa o seu cadastro e logo em seguida mostra a página do seu perfil. Neste fluxo, seu navegador precisou:

  • Enviar uma requisição para obter a página de cadastro (GET /cadastro.html);
  • Enviar os dados que você preencheu no formulário (POST /cadastro.html);
  • Mostrar a página do seu perfil (GET /meu_perfil.html).

Todas as operações de leitura foram realizadas utilizando o verbo GET. Quando o seu navegador solicitou as páginas, ele enviou uma requisição GET que foi respondida pelo servidor com outra mensagem HTTP, onde o conteúdo da mensagem era a página solicitada. Já a operação de escrita (ou seja, a de cadastro) utilizou o verbo POST, onde a mensagem que o seu navegador enviou tinha como conteúdo os dados que você preencheu. O servidor recebe esses dados e os salva em algum lugar. Enquanto a URI identifica qual recurso deve ser acessado, o verbo define a ação que se deseja realizar sobre o recurso.

Os cabeçalhos são um conjunto de chaves e valores com dados adicionais sobre a mensagem, como, por exemplo, o tamanho da mensagem, a sua codificação, o tempo que o cliente pode armazenar o conteúdo em cache, entre outros. Existem inúmeros headers padrão, e clientes podem enviar headers específicos da sua aplicação.

O código de status devolvido em uma resposta a um cliente é um valor que indica para o cliente o estado da solicitação. Por exemplo, acessar um recurso que não existe gera uma resposta com status 404 Not Found.

Agora sabemos que, quando acessamos a url da nossa aplicação no servidor, o navegador irá realizar uma requisição GET /. Como configuramos nossa aplicação para responder a um GET para a uri / (através do app.MapGet("/", ...)) com uma mensagem, esta mensagem é devolvida ao navegador, que a exibe.

Todos os navegadores recentes possuem ferramentas de desenvolvedor onde você pode observar a atividade de rede (ou seja, as requisições que foram ou estão sendo feitas). Tente descobrir como você pode abrir estas ferramentas, e observe a atividade do navegador quando você acessa a sua aplicação.

No próximo capítulo, vamos começar a definir os endpoints do escopo que definimos para desenvolver a aplicação da biblioteca.