<script>
  import VscDebugging                from "../../assets/img/37_vsc_debugging.png";
  import BrowserHomeEmpty            from "../../assets/img/38_browser_home_empty.png";
  import BrowserNaoConseguiuConectar from "../../assets/img/39_browser_nao_conseguiu_conectar.png";
  import BrowserPortaErrada          from "../../assets/img/40_browser_porta_errada.png";
  import BrowserHelloWorld           from "../../assets/img/41_browser_hello_world.png";
  import BrowserKonnichiwa           from "../../assets/img/42_browser_konnichiwa.png";
  import BrowserNetwork              from "../../assets/img/43_browser_network.png";
</script>

<svelte:head>
  <title>Criando e executando endpoints</title>
</svelte:head>

<section>
  <h1>Criando e executando endpoints</h1>

  <nav>
    <a href="/">Início</a>
  </nav>

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

  <section>
    <h2>Iniciando o serviço Web</h2>

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

  <pre><code>{`var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.Run();`}</code></pre>

    <p>
      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 <code>launchSettings.json</code>).
      Nenhuma outra configuração adicional foi realizada, nem nenhum endpoint foi definido. Sua aplicação apenas inicia e fica escutando na porta correspondente.
    </p>

    <div>
      <img src="{VscDebugging}" alt="">
    </div>

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

    <p>
      Abra uma nova aba no seu navegador de internet, e, na barra de endereço, escreva <code>http://localhost:&lt;porta&gt;</code>, onde <code>&lt;porta&gt;</code> é o número que está definido no seu <code>launchSettings.json</code> (no meu caso, este número é 5000, portanto o endereço que
      eu devo digitar é <code>http://localhost:5000</code>. Você pode alterar o seu <code>launchSettings.json</code> 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.
    </p>

    <div>
      <img src="{BrowserHomeEmpty}" alt="">
    </div>

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

    <div>
      <img src="{BrowserNaoConseguiuConectar}" alt="">
    </div>

    <p>
      Ou esta, onde digitei uma porta aleatória:
    </p>

    <div>
      <img src="{BrowserPortaErrada}" alt="">
    </div>
  </section>

  <section>
    <h2>Criando o primeiro endpoint</h2>

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

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

<pre><code>{`var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

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

app.Run();`}</code></pre>

    <p>
      Note que adicionamos o seguinte trecho de código:
    </p>

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

    <p>
      <code>app</code> é uma instância de <code><a href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.webapplication?view=aspnetcore-9.0" target="_blank">WebApplication</a></code> 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 <code>MapGet(string, Delegate)</code>, que fará com que ela responda ao verbo <code>GET</code> no caminho <code>/</code> (ou seja, a raíz), com uma mensagem simples.
    </p>

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

    <div>
      <img src="{BrowserHelloWorld}" alt="">
    </div>

    <p>
      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:
    </p>

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

    return saudacoes[Random.Shared.Next(saudacoes.Length)];
});`}</code></pre>

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

    <div>
      <img src="{BrowserKonnichiwa}" alt="">
    </div>
  </section>

  <section>
    <h2>Estrutura de uma requisição HTTP</h2>

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

    <p>
      <a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP" target="_blank">HTTP</a> é um acrônimo para <em>Hypertext Transfer Protocol</em>, que é um protocolo para <em>troca de mensagens</em> entre
      nós em uma rede em uma arquitetura cliente-servidor. 
    </p>

    <p>
      Este protocolo define um padrão para que um <em>cliente</em> tenha acesso a um <em>recurso</em> 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.
    </p>

    <p>
      Esta solicitação ocorre através de uma troca de mensagens entre o cliente e o servidor. O cliente envia uma mensagem de <em>solicitação</em>, e o servidor devolve uma mensagem de <em>resposta</em>.
      Estas mensagem possuem uma estrutura composta por um
      <em><a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Reference/Methods" target="_blank">verbo</a></em>,
      um <em><a href="https://developer.mozilla.org/en-US/docs/Web/URI" target="_blank">identificador de recurso</a></em>,
      <em><a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Reference/Headers" target="_blank">cabeçalhos</a></em>, e, opcionalmente, um <em>conteúdo</em>.
      Além disso, toda <em>resposta</em> a uma mensagem enviada por um cliente possui também um <em><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status" target="_blank">código de status</a></em>.
    </p>

    <p>
      O <em>identificador do recurso</em> (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 <a href="https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs" target="_blank">https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs</a>,
      a parte que corresponde à URI é <a href="https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs" target="_blank">/wiki/Plan_9_from_Bell_Labs</a>. Se não há nada após a barra, então a URI é apenas /.
    </p>

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

    <p>
      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:
    </p>

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

    <p>
      Todas as operações de leitura foram realizadas utilizando o verbo <code>GET</code>. Quando o seu navegador solicitou as páginas, ele enviou uma requisição <code>GET</code>
      que foi respondida pelo servidor com outra mensagem HTTP, onde o <em>conteúdo</em> da mensagem era a página solicitada.
      Já a operação de escrita (ou seja, a de cadastro) utilizou o verbo <code>POST</code>, 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 <em>qual</em> recurso deve ser acessado, o verbo define a <em>ação</em> que se deseja realizar sobre o recurso.
    </p>

    <p>
      Os cabeçalhos são um conjunto de chaves e valores com dados adicionais <em>sobre</em> 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.
    </p>

    <p>
      O <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status" target="_blank">código de status</a> devolvido em uma resposta a um cliente é um valor que
      indica para o cliente o <em>estado da solicitação</em>. Por exemplo, acessar um recurso que não existe gera uma resposta com status <code>404 Not Found</code>.
    </p>

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

    <p>
      Todos os navegadores recentes possuem <a href="https://developer.chrome.com/docs/devtools/overview">ferramentas de desenvolvedor</a> 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.
    </p>

    <div>
      <img src="{BrowserNetwork}" alt="">
    </div>

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

    <nav>
      <span>Próximo:</span>
      <a href="/endpoints_2">Definindo os endpoints da Biblioteca</a>
    </nav>
  </section>

</section>