Tópicos Especiais

Chrysthian Simão

Introdução a Minimal APIs

Revisão dos exercícios

Calculadora geométrica

Crie um programa de console que tenha uma classe abstrata "Shape" e exiba a *área* e *perímetro* das seguintes formas geométricas:

  • Círculo
  • Triângulo
  • Retângulo

Experimento Nasa

Git

Git

Repositório de códigos para poupar a sua pressão sanguínea e pra ajudar você do futuro.

 

Na universidade está instalado nas máquinas, mas em casa, você precisa instalar ele

Git

Não tem uma conta? hora de fazer uma

Agora!
Já!
Nesse instante!

Git

Você pode instalar a ferramenta da sua preferência para trabalhar se quiser, mas eu vou mostrar via linha de comando mesmo.


O GitHub tem o github desktop por exemplo.

Git

Como eu sei que instalou corretamente?

git --version

Usuário

A primeira coisa que você deve fazer ao instalar Git é configurar seu nome de usuário e endereço de e-mail.

Isto é importante porque cada commit usa esta informação, e ela é carimbada de forma imutável nos commits que você começa a criar.

Usuário

Configurando usuário global

git config --global user.name "Fulano de Tal"
git config --global user.email fulanodetal@exemplo.br

git config --list 

Clonando um repositório

Para pegar código de um repositório, dizemos que estamos clonando ele, isso quer dizer que tudo o que ele tem, na versão mais atual vai ser copiado para o seu equipamento.

Clonando um repositório

git clone https://github.com/chrysthian/up.git

Git pull

Como o comando clone só copia o repositório *naquele momento*, manter o projeto atualizado requer que você atualize ele.

 

Por exemplo se o professor enviar uma atualização de exercício ou código depois que você clonou.

Git pull

git pull

git pull (só que menor)

Gerenciando alterações

Nos arquivos locais (na sua máquina) você pode fazer o que achar melhor.

 

Mas você só pode enviar código para um repositório que você tem acesso, sendo como dono ou parte do time (isso é configurado no próprio repositório).

Add

É muito comum adicionarmos arquivos novos ao trabalhar em uma solução de código, mas para isso precisamos dizer ao repositório para versionar os arquivos novos também

Commit

A ação de commit, é salvar e versionar os arquivos alterados em relação ao código do repositório.

 

As alterações realizadas podem ser comparadas linha a linha, e é possível "voltar no tempo" entre as versões do código que passaram por um commit.

Commit

Commit é uma ação LOCAL!

O repositório ainda não sabe das suas alterações!!!

Push

Uma vez adicionados os arquivos novos, salvo as alterações nos arquivos antigos através de um commit, é hora de avisar o repositório que a versão do seu trabalho foi atualizada.

Push

Aqui entra o push, você "empurra" o código para o repositório.

Gerenciando alterações

git pull
git add .
git commit -m"mensagem curta sobre as alterações"
git push

Gerenciando alterações

VS Code resolve isso pra você, pode usar? pode

 

A vantagem do terminal é que os comandos são os mesmos sempre, já interface pode mudar de ferramenta pra ferramenta, então tem que acostumar com cada uma.

 

A gosto do freguês desde que entenda o conceito

Resolvendo conflitos

Quando duas pessoas mexem em um mesmo trecho de código, como o repositório sabe qual é o correto?

 

Isso acontece quando esse cenário é identificado em um pull, por isso o primeiro comando antes de enviar código deve ser pull

Resolvendo conflitos

Quando o conflito aparece o git tentará resolver os conflitos automaticamente, (por exemplo somando alterações em um mesmo arquivo, mas trechos diferentes de código)

 

Mas se ainda assim existir conflitos eles precisam ser resolvidos manualmente

Resolvendo conflitos

O próprio VS Code trará uma listagem de arquivos que precisam de uma intervenção do desenvolvedor para que sejam solucionados.

 

Uma vez resolvidos, é necessário um commit e um push.

 

Mas claro, TESTE antes de enviar a sua atualização ou todos que estiverem consumindo o repositório podem acabar puxando um código quebrado.

Caminhos "alternativos"

Algumas pessoas tentam postegar o uso do git ao acessar os sites que contém os repositórios e navegar pelo código diretamente no navegador.

 

Embora as ferramentas como github e bitbucket tenham essa facilidade, é preferível clonar o repositório de fato, permitindo o uso de IDEs, gerar alterações locais, além de aplicações mais complexas precisarem de um processo de build antes de rodar.

 

Consulte pelo navegador somente em casos de consultas rápidas, mas via de regra, clone o repositório

ASP.NET e Minimal APIs

Tópicos Especiais

Desenvolvimento de projetos web

 

  • Backend com C# e .Net Core
     
  • Frontend com React e TS

Cliente x Servidor

Cliente x Servidor

Cliente

Servidor

(estamos aqui)

Navegadores, comofas?

  • Seu navegador (cliente) faz requisições para um servidor
     
  • O servidor processa essa requisição
     
  • Seu navegador recebe uma resposta
     
  • O Navegador baixa os arquivos localmente (cache)
     
  • Usando as informações locais, o browser as interpreta e exibe na tela o resultado

HTTP é a sigla para Hypertext Transfer Protocol, que em português significa Protocolo de Transferência de Hipertexto.

Trata-se de um padrão de comunicação utilizado para a transferência de informações na World Wide Web e em outros sistemas de rede.

Protocolo HTTP

Ele é a base da comunicação na internet e permite que os navegadores solicitem páginas da web e outros recursos de servidores, bem como enviem informações de volta para esses servidores.

Protocolo HTTP

http, a parte antes de "://" é o que chamamos de URL Scheme.

 

Nesse caso, estamos falando para o navegador usar o Hypertext Transfer Protocol, o HTTP.

URL

Existem outros esquemas, tais como: https, FTP, mailto.

 

Tudo que vier depois de "://" é específico do protocolo que estiver sendo utilizado.

URL

https://slides.com/chrysthian/

Protocolo HTTP

Hypertext Transfer Protocol Secure (HTTPS) é uma extensão do HTTP que usa criptografia de dados, ou seja é igual, só que diferente

Endereços como google.com são na verdade o nome do servidor que armazena nosso recurso.

Nosso navegador vai realizar um processo conhecido como DNS Lookup para traduzir o nome em um endereço de rede (IP) e vai enviar a requisição para esse endereço.

DNS
Domain Name System

A sua função não é hospedar sites ou aplicações que criamos, mas sim permitir que as requisições cheguem aos locais corretos.

 

Um servidor DNS é feito única e exclusivamente para a tradução de domínios para endereços de IP

DNS
Domain Name System

https://slides.com/chrysthian/

DNS

18.211.49.95

Url path é o que aparece depois do DNS.

 

O servidor irá identificar qual é o recurso específico que deve devolver para este caminho quando a requisição chega

URL PATH

Podem ser recursos a serem interpretados como uma página

OU

Arquivos que fazem parte da apresentação como arquivos CSS, JS, vídeos e imagens.

URL PATH

Na nossa disciplina, uma aplicação desenvolvida em ASP.NET irá tratar a requisição no servidor, fará uma consulta em um banco de dados e o recurso que será devolvido para ser construído dinamicamente por esta aplicação.

URL PATH

https://slides.com/chrysthian/

URL PATH

Esse número 80 representa o número da porta que o servidor está usando para “ouvir” requisições HTTP.

A porta 80 é a padrão e é opcional no caso do uso do endereço em um navegador, então, normalmente você não vê esse 80 nas URLs.

PORT

https://slides.com:80/chrysthian

É mais comum especificarmos esta porta quando estamos testando a aplicação em ambiente de homologação/testes.

 

Como por exemplo http://localhost:3000

PORT

http://localhost:3000

URL PATH

Aba Network do seu browser

 Ctrl+Shift+J (Edge)

F12 (Chrome, Firefox)

Status

Para saber se uma requisição foi bem sucedida ou não há um padrão de códigos de status.

 

Respostas Informativas (100 – 199)
Respostas bem-sucedidas (200 – 299)
Mensagens de redirecionamento (300 – 399)
Respostas de erro do cliente (400 – 499)
Respostas de erro do servidor (500 – 599)

API

As APIs (Application Programming Interfaces) são construções disponíveis nas linguagens de programação que permitem a desenvolvedores criar funcionalidades complexas mais facilmente.

 

Tais construções abstraem o código mais complexo, proporcionando o uso de sintaxes mais simples em seu lugar.

API

Por exemplo, a API Web Áudio fornece construções JavaScript simples para manipular áudio em seu navegador - pegar uma faixa de áudio, alterar o volume dela, aplicar efeitos, etc.

API

Por trás dos panos, o navegador utiliza códigos complexos de baixo nível (ex: C++) para realizar o processamento de áudio de fato. Como foi dito anteriormente, essa complexidade toda é abstraída de você pela API.

WEB API com protocolo HTTP

Então na nossa solução vamos criar uma API web, com requisições e respostas através do protocolo HTTP

Hands On Exercise

Minimal example

  • Crie uma pasta vazia
  • Abra no VS Code
  • CTRL + SHIFT + P
  • .NET New Project...
  • ASP.NET Core Empty
  • Pegue o conteúdo da pasta "Minimal API" do meu repositório e substitua na pasta do projeto (cuidado onde colocar!)
  • Apague o Program.cs (não precisamos de dois métodos Main)
  • F5 pra rodar

REST API

REpresentational State Transfer (REST)

REST API

REST API

http://www.icecream.com/api/flavors

Endpoint

REST API

C reate
 

R ead
 

U pdate
 

D elete

Operações HTTP

Operações de uma aplicação

Post
 

Get
 

Put
 

Delete

REST API

Headers

Informações sobre a requisição em sí, podendo conter dados de autenticação

Operação

Post, Get, Put, Delete

Endpoint

URL

Parâmetros / Corpo

Quando necessário

Request












 

REST API - GET

Headers

 

Operação

GET

Endpoint

http://www.icecream.com/api/flavors

Parâmetros / Corpo

 

Request











 

REST API - GET

Response











 

[
	{ 
    	"id": 1, 
    	"name": "Morango"
	},
	{ 
    	"id": 3, 
    	"name": "Chocolate"
	},
  	{ 
    	"id": 18, 
    	"name": "Pêra"
	},
]

REST API - PUT

Headers

 

Operação

PUT

Endpoint

http://www.icecream.com/api/flavors/18

Parâmetros / Corpo

   {  "id": 18,  "flavor": "Uva"}

Request











 

REST API - PUT

Response







 

[
  	{ 
    	"id": 18, 
    	"name": "Uva"
	},
]

REST API - POST

Headers

 

Operação

POST

Endpoint

http://www.icecream.com/api/flavors

Parâmetros / Corpo

   { "flavor": "Framboesa"}

Request











 

REST API - POST

Response







 

[
  	{ 
    	"id": 2, 
    	"name": "Framboesa"
	},
]

REST API - DELETE

Headers

 

Operação

DELETE

Endpoint

http://www.icecream.com/api/flavors/1

Parâmetros / Corpo

  

Request











 

REST API - DELETE

Response







 

[
  	{ 
    	"id": 1, 
    	"name": "Morango"
	},
]

Nuget.org

O NuGet é o gerenciador de pacotes da microsoft, assim como o NPM pra Node e o Maven pra Java.

 

Ele permite baixar e gerenciar bibliotecas C#.

Nuget.org

As bibliotecas são instaladas globalmente por padrão, diferente de alguns gerenciadores de pacote, como o NPM que instala localmente e por projeto.

 

  • Windows: %userprofile%\.nuget\packages
  • Mac/Linux: ~/.nuget/packages

ORM (Object Relational Mapping)

ORM

PRO

 

  • Facilita a implementação de um Modelo
  • Reduz drasticamente o código necessário
  • Cuida de Abstração de banco de dados
  • Cache

ORM

CONTRA

  • Sofre drasticamente com Queries pesadas (sum, count, having)
  • Relativamente difícil debugar e corrigir as queries geradas

Entity Framework

Entity framework é uma forma do C# facilitar e abstrair o acesso a um banco de dados, através de ORM.

 

Criamos classes para representar nossas entidades e relacionamentos do banco de dados.

Entity Framework

As respostas são convertidas em JSON automagicamente.

 

Só precisamos intalar essas bibliotecas para podermos utilizá-los

Entity Framework

dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Sqlite

Entity Framework (.NET 6 ou 7)

dotnet add package Microsoft.EntityFrameworkCore.Tools --version 7.0.7
dotnet add package Microsoft.EntityFrameworkCore.Design --version 7.0.14
dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 7.0.17

Model-View-Controller

Brute Force Install

C# Dev Kit

Tenta instalar a extensão

 

Nao vai dar boa

 

Vai aparecer essa mensagem

 

Clica nela

Vai te levar pra um link que vai baixar o arquivo

Volte no VS Code e clique nesse botão

Procure o arquivo baixado

Vai dar erro algumas vezes. Clique em Try Again ate a instalação ser concluída

Ali ja consta como instalado. Mas ta branco o selo de verificação. Só fechar o VS Code e abrir se novo para ele validar a extensão

As extensões que foram, baixadas

 

(guarde esse truque para o futuro)

Swagger

dotnet add package NSwag.AspNetCore

Swagger (Builder C#)

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddOpenApiDocument(config =>
{
	config.DocumentName = "TodoAPI";
    config.Title = "TodoAPI v1";
    config.Version = "v1";
});

Swagger (WebApplication C#)

if (app.Environment.IsDevelopment())
{
	app.UseOpenApi();
	app.UseSwaggerUi(config =>
	{
		config.DocumentTitle = "Todo API";
		config.Path = "/swagger";
		config.DocumentPath = "/swagger/{documentName}/swagger.json";
		config.DocExpansion = "list";
	});
}   

Todos os pacotes até agora

dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet tool install --global dotnet-ef
dotnet add package NSwag.AspNetCore

Todos os pacotes até agora (.NET 7)

dotnet add package Microsoft.EntityFrameworkCore.Tools --version 7.0.7
dotnet add package Microsoft.EntityFrameworkCore.Design --version 7.0.14
dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 7.0.17
dotnet tool install --global dotnet-ef --version 7.0.7
dotnet add package NSwag.AspNetCore

Hands On Exercise

Minimal example

  • Crie uma pasta vazia
  • Abra no VS Code
  • CTRL + SHIFT + P
  • .NET New Project...
  • ASP.NET Core Empty
  • Pegue o conteúdo da pasta "Minimal API" do meu repositório e substitua na pasta do projeto (cuidado onde colocar!)
  • Apague o Program.cs (não precisamos de dois métodos Main)
  • F5 pra rodar

Hands On Exercise 2

YOUR Minimal example

  • Crie um projeto do zero que tenha a estrutura que eu mostrei, MAS com um novo tipo de entidade, é uma lista de tarefas (com Id, Nome e um indicativo se está completa)
Endpoint Request Response
GET /tasks - Array de todas as Tarefas
GET /tasks/complete - Array de todas as Tarefas completas
GET /tasks/{id} - Tarefa com id escolhido
POST /tasks Tarefa Tarefa nova com seu Guid
PUT /tasks/{id} Tarefa Tarefa atualizada
DELETE /tasks/{id} Tarefa Tarefa removida

Banco de Dados

SQLite

Ao invés de trabalhar com dados em memória, vamos guardar isso de forma permanente com um banco de dados bem simples.

 

SQLite é um BD mínimo que resolve nossos problemas.

SQLite

Baixe o bundle

SQLite

using Icecream.Models;
using Microsoft.EntityFrameworkCore;

namespace Icecream.Data
{
    public class AppDbContext : DbContext
    {
        public DbSet<Flavor> Flavors { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlite("DataSource=icecream.sqlite;Cache=Shared");
    }
}

Vamos criar o nosso Data Context, que é a representação do banco de dados em memória. Crie uma pasta "Data" e coloque esse código para representar suas entidades (alterando conforme necessário).

C# Record

O C# introduziu um novo tipo para estruturas de dados, chamado Record, que permite ter recursos de objetos em estruturas mais simples.

 

Este tipo é o caso perfeito para nosso cenário, já que não teremos nenhum comportamento aqui, apenas dados.

namespace Icecream.Models
{
    public record Flavor(Guid Id, string Name);
}

C# Record

Podemos usar classes normais, e para estruturas mais complexas como por exemplo, com relacionamentos, mas por hora a estrutura é mais simples de compreender.

namespace Icecream.Models
{
    public record Flavor(Guid Id, string Name);
}

Migrations

O que seria melhor que manualmente criar o nosso banco de dados? A nossa aplicação criar o banco de dados pra gente usando bibliotecas!

Migrations

Precisa das devidas bibliotecas instaladas do Entity Framework!
 

Senão você toma um xingão!

dotnet ef migrations add InitialCreation
dotnet ef database update

Todos os pacotes até agora

dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet tool install --global dotnet-ef
dotnet add package NSwag.AspNetCore

Todos os pacotes até agora (.NET 7)

dotnet add package Microsoft.EntityFrameworkCore.Tools --version 7.0.7
dotnet add package Microsoft.EntityFrameworkCore.Design --version 7.0.14
dotnet add package Microsoft.EntityFrameworkCore.Sqlite --version 7.0.17
dotnet tool install --global dotnet-ef --version 7.0.7
dotnet add package NSwag.AspNetCore

Migrations

Da mesma forma que nós associamos os objetos da nossa aplicação as chamadas de API REST, o Entity Framework vai associar os mesmos objetos a tabelas do banco de dados!

Quero trabalhar meu Banco de Dados!

Cuidado aqui, se você alterar a estrutura do seu banco FORA da aplicação, não tem como recriar a estrutura usando o Entity Framework!!!

 

Mas para ver o que foi criado, podemos usar o DB Browser (é um aplicativo portável, ta suave)

Quero trabalhar meu Banco de Dados!

Se sua estrutura de classes mudar, prefira usar o seguinte:

dotnet ef migrations add [NomeResumidoDaAlteracao]
dotnet ef database update

Cria uma nova migration

Atualiza seu BD

Migrations

Agora que temos um contexto precisamos adicionar isso ao builder, que monta a nossa estrutura de aplicação web.

builder.Services.AddDbContext<AppDbContext>();

WebApplication app = builder.Build();

Essa linha tem que aprecer ANTES do builder.Build();

Diferenças importantes!

app.MapGet("/api/flavors", (AppDbContext context) =>
{
   var flavors = context.Flavors;
   return flavors is not null ? Results.Ok(flavors) 
      : Results.NotFound();
}).Produces<Flavor>();

Agora nossa aplicação pode usar nossa classe de contexto (passado por parâmetro) pra acesar o banco

Para o Swagger entender o que estamos retornando colocamos a instrução no final do método .Produces<Flavor>();

O que temos aqui então?

O que temos aqui então?

TAMBÉM resolveu pra gente!
(entity framework com migrations)

.NET resolveu pra gente!
(mapGet, mapPost, etc...)

Hands On Exercise (LVL UP!)

  • Usando a estrutura do exercício de Tarefas, vamos agora alterar para consultar o Banco de Dados!
Endpoint Request Response
GET /tasks - Lista de todas as Tarefas
GET /tasks/complete - Lista de todas as Tarefas completas
GET /tasks/{id} - Tarefa com id escolhido
POST /tasks Tarefa Tarefa nova com seu Guid
PUT /tasks/{id} Tarefa Tarefa atualizada
DELETE /tasks/{id} Tarefa Tarefa removida

Avaliação A2!

  • Somente backend (frontend vai pra A1)
  • Utilizar Rest API com pelo menos 7 endpoints
  • GET, POST, PATCH(!), PUT e DELETE
  • Persistência no banco (sem relacionamentos)
  • O tema que você quiser, defendendo o código durante a apresentação

Tópicos Especiais 3

By Chrysthian Simão

Tópicos Especiais 3

  • 300