View on GitHub

aulas-programacao-web

Materiais de Aula - Programação de Computadores com tecnologias Web

ASP.NET Core WebApi - Hello World

📽 Veja esta vídeo-aula no Youtube

📽 Veja também esta live com o mesmo conteúdo e uma abordagem diferenciada

Para criarmos nossa primeira API de backend usaremos o framework ASP.NET Core. Ele usa o conceito orientado a objetos na arquitetura MVC, que se baseia em 3 pilares: Model, View e Controller, onde:

Vamos usar o template webapi para iniciar nosso projeto, e depois personalizá-lo.

Usando o template inicial

Crie o projeto usando o template webapi, assim como você usaria console.

dotnet new webapi

Serão criados vários arquivos, entre eles:

Há também uma API de exemplo, que retorna uma lista aleatória de previsões do tempo fake, somente para teste da aplicação. Vamos usá-la para ver se nossa aplicação está rodando.

Execute o projeto normalmente, usando dotnet run. A saída deve ser algo do tipo:

info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\caminho\do\projeto\nomeDoProjeto

Atente-se às informações:

Vá até o navegador e acesse https://localhost:5001 e http://localhost:5000. Você não achará nenhum conteúdo, já que nada está sendo entregue para a raíz do site. Porém, há conteúdo sendo servido pela controller WeatherForecast. Ela responde à rota /WeatherForecast com um arranjo JSON contendo o seu resultado. Para vê-lo, então, precisamos acessar https://localhost:5001/WeatherForecast ou http://localhost:5000/WeatherForecast.

Perceba que você não conseguirá acessar nenhum deles, devido à configuração de segurança. Podemos simplesmente aceitar o acesso ao site inseguro, ou desabilitar o redirecionamento automático para HTTPS, comentando a linha abaixo em Startup.cs:

    // app.UseHttpsRedirection();

Pare o servidor e o inicie novamente. Agora você conseguirá acessar a versão sem HTTPS, em http://localhost:5000/WeatherForecast, e verá algo como:

[
  {
    "date": "2020-10-27T12:31:50.0427198-03:00",
    "temperatureC": 1,
    "temperatureF": 33,
    "summary": "Freezing"
  },
  {
    "date": "2020-10-28T12:31:50.0427449-03:00",
    "temperatureC": 46,
    "temperatureF": 114,
    "summary": "Scorching"
  },
  {
    "date": "2020-10-29T12:31:50.042746-03:00",
    "temperatureC": 30,
    "temperatureF": 85,
    "summary": "Hot"
  },
  {
    "date": "2020-10-30T12:31:50.0427462-03:00",
    "temperatureC": 24,
    "temperatureF": 75,
    "summary": "Cool"
  },
  {
    "date": "2020-10-31T12:31:50.0427468-03:00",
    "temperatureC": 7,
    "temperatureF": 44,
    "summary": "Bracing"
  }
]

Para habilitar HTTPS, precisamos da maiores configurações, o que não é o foco agora.

🐱‍👤 Você também pode acessar a listagem de todos os endpoints disponíveis e sua documentação a partir da url /swagger.

Criando uma controller simples

Vamos criar uma controller que responda à rota /HelloWorld e nos retorne um objeto JSON { mensagem: "Hello Dev Web!" }.

Primeiro vamos excluir os arquivos do exemplo WeatherForecast. Exclua a model WeatherForecast.cs, e a controller Controllers\WeatherForecastController.cs.

Não vamos criar um model, porque nosso resultado é muito simples. Vamos direto para a controller. Crie na pasta Controllers um arquivo com o nome da rota desejada, mais a palavra Controller, e a extensão .cs. No caso, utilize Controllers\HelloWorldController.cs. Seu conteúdo:

using System;
using Microsoft.AspNetCore.Mvc;

namespace nomeDoProjeto.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class HelloWorldController : ControllerBase
    {
        [HttpGet]
        public Object Get()
        {
            return new { mensagem = "Hello Dev Web!" };
        }
    }
}

Linha a linha:

Ao rodar esse programa, a aplicação passa a escutar http://localhost:5000/HelloWorld, e retornar o JSON abaixo:

{
  "mensagem": "Hello Dev Web!"
}

Nosso backend está funcional.

Frontend integrada

Podemos acessar essa API usando Fetch. Para isso, vamos colocar arquivos HTML, CSS e JavaScript em nossa aplicação.

Primeiro, precisamos ativar o recurso que entrega arquivos estáticos. Adicione as linhas em Startup.cs, antes de app.UseRouting():

app.UseDefaultFiles();
app.UseStaticFiles();

Agora, crie a pasta /wwwroot, e nele coloque sua aplicação. Por exemplo:

Marcação:

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello Dev Web</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <img src="imagens/logo.png" alt="Dev Web">
    <h1>Temos uma mensagem para você:</h1>
    <div id="mensagem"></div>
    <script src="index.js"></script>
</body>
</html>

Estilização

body {
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
}

body > * {
  flex: 1;
}

#mensagem {
  color: #004545;
  font-size: 2em;
}

Script:

const iniciar = async () => {
    const mensagem = document.getElementById("mensagem");
    const response = await fetch('/HelloWorld');
    const result = await response.json();
    mensagem.innerHTML = result.mensagem;
};

document.addEventListener('DOMContentLoaded', iniciar);

Você terá uma estrutura assim:

Ao acessar, você verá algo do tipo:

Retornando um objeto complexo

Digamos que gostaríamos de retornar um objeto com uma estrutura mais complexa, por exemplo, uma mensagem um link para o Dev Web.

O ideal é criar uma classe que especifique esse formato explicitamente. Normalmente a chamamos de DTO, ou Data Transfer Object. Vamos criar então uma model chamada HelloWorldModel, em /Models, com essa finalidade.

namespace nomeDoProjeto.Models
{
    public class HelloWorldModel
    {
        public string mensagem { get; set; }
        public string url { get; set; }
    }
}

Agora, vamos alterar a controller para retornar um objeto desse tipo.

using Microsoft.AspNetCore.Mvc;
using nomeDoProjeto.Models; // referência às models

namespace nomeDoProjeto.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class HelloWorldController : ControllerBase
    {
        [HttpGet]
        public HelloWorldModel Get() // o retorno é uma model
        {
            // Cria uma instância de HelloWorldModel, e a retorna
            var resultado = new HelloWorldModel
            {
                mensagem = "Hello Dev Web!",
                url = "https://github.com/ermogenes/aulas-programacao-web/"
            };
            return resultado;
        }
    }
}

O resultado passa a ser:

{
  "mensagem": "Hello Dev Web!",
  "url": "https://github.com/ermogenes/aulas-programacao-web/"
}

E podemos alterar o script para considerar o link.

mensagem.innerHTML = `<a href="${result.url}">${result.mensagem}</a>`;