Fundamentos para Web APIs com .NET: Uma Introdução ao Essencial com Entity Framework

Yago Peixinho - Aug 1 - - Dev Community

Desenvolva a API DessaVezEuNaoEsqueco. No meio desse desenvolvimento, vamos mergulhar nos conceitos do .NET e API.

Fundamentos Essenciais para Web APIs com .NET: Uma Introdução ao essencial com Entity Framework e SQLite. Entenda os conceitos por trás de uma Web API utilizando o .NET 8.0 e o Entity Framework Core.

Esse artigo é destinado para todos os níveis de programadores, desde os menos experientes até os mais avançados. Nosso objetivo é compreender o que acontece por trás dos panos e nutrir alguns conhecimentos essenciais acerca de uma API (Application Programming Interface) e seus comportamentos.

Sumário:

  • Compreendendo .NET & C#
  • Entendendo o que é uma API
    • Protocolo HTTP
    • JSON
    • HTTP Código de Resposta (Status Code)
  • Criação do projeto DessaVezEuNaoEsquecoAPI
    • Sobre o Projeto
    • Instalação
      • Ubuntu
      • Windows
    • Estrutura Inicial de uma aplicação .NET 8
      • Program.cs
      • appsettings.json
      • Dependencies
    • Entendendo as Entidades (Models)
      • Características de Entidades em .NET
      • Criando Nossa Primeira Entidade
    • Entendendo e o que é uma ORM & Entity Framework Core
      • Data Annotations na nossa Entidade com o Entity Framework
      • Instalando o Entity Framework
      • Compreendendo o que é NuGet
      • Instalando o Pacote Nuget do Entity Framework
      • Configurando o Entity Framework em nosso ambiente
      • Configurar o Contexto do Banco de Dados no arquivo Program.cs
      • Migração de Banco de Dados
      • Migração com o Entity Framework
    • Controllers
      • Criando nossos Controllers
      • Configurando Swagger para realizarmos solicitações HTTP
      • Criando arquivo AtividadesController.cs
      • Definindo o Método GET
      • Definindo o Método POST
      • Definindo o Método GET Individual
      • Vamos definir o método PUT
      • Definindo o Método DELETE
  • Conclusão & Resumo

Dicas para leitura do artigo!

  1. Pit-stop
    Em momentos estratégicos do artigo, faremos pausas (geralmente durante o desenvolvimento do projeto) para exemplificar algum conceito ou revelar o que ocorre nos bastidores. Esses intervalos também são uma oportunidade para você descansar e evitar a fadiga mental.

  2. Simbologia da Tartaruga
    Durante a leitura deste artigo e o desenvolvimento do projeto DessaVezEuNaoEsqueco, você encontrará o símbolo de uma tartaruga 𓆉 ao lado de novos conceitos Este símbolo indica que o conceito associado ainda não foi abordado em detalhes. Certifique-se de prestar atenção a esses pontos, pois eles sinalizam que uma explicação será fornecida posteriormente.

Antes de mergulharmos fundo, você pode conferir o repositório no Github. Os códigos estão comentados, exemplificando claramente os conteúdos tratados.

GitHub logo yagopeixinho / DessaVezEuNaoEsquecoAPI

DessaVezEuNaoEsquecoAPI, desenvolvida em .NET 8.0 & C#, é a sua solução definitiva para garantir que você nunca mais esqueça de nada! Seja uma lista de compras, tarefas diárias, itens para uma viagem ou qualquer outra coisa importante, essa API oferece uma interface simples e intuitiva para gerenciar suas listas e lembretes de maneira eficiente.

Uma Introdução ao Essencial com Entity Framework e SQLite.

IntroduçãoContatoLicença

Introdução

Desenvolva a API DessaVezEuNaoEsqueco. No meio desse desenvolvimento, vamos mergulhar nos conceitos do .NET e API.

Fundamentos Essenciais para Web APIs com .NET: Uma Introdução à Propedêutica (corpo de ensinamentos introdutórios ou básicos de uma disciplina; ciência preliminar, introdução.) com Entity Framework e SQLite. Entenda os conceitos por trás de uma Web API utilizando o .NET 8.0 e o Entity Framework Core.

Esse artigo é destinado para todos os níveis de programadores, desde os menos experientes até os mais avançados. Nosso objetivo é compreender o que acontece por trás dos panos e nutrir alguns conhecimentos acerca de uma API (Application Programming Interface) e seus comportamentos.

Sumário:

  • Compreendendo .NET & C#
  • Entendendo o que é uma API
    • Protocolo HTTP
    • JSON
    • HTTP Código de Resposta (Status Code)
  • Criação do projeto DessaVezEuNaoEsquecoAPI
    • Sobre o Projeto
    • Instalação
      • Ubuntu




Entendendo a diferença entre C# e .NET

Comumente, vemos muitas referências a C# e .NET, mas você sabe exatamente quem é quem?

A resposta é mais direta do que parece…

O .NET é uma plataforma de desenvolvimento criada pela Microsoft, projetada para suportar a criação de diversos tipos de aplicações, como aplicativos móveis, desktop e web. Ele inclui uma vasta gama de ferramentas, bibliotecas e runtimes, proporcionando um ambiente robusto e a infraestrutura necessária para desenvolver, executar e gerenciar aplicações de forma eficiente.

Já o C# (pronunciado "C Sharp") é uma linguagem de programação moderna, orientada a objetos, também desenvolvida pela Microsoft. É versátil e pode ser utilizada para desenvolver uma ampla variedade de aplicações, desde websites até jogos. Originalmente, C# era uma linguagem proprietária da Microsoft. No entanto, a partir de 2014, começou a transformação para open-source, permitindo que a comunidade global tivesse acesso e pudesse contribuir para a evolução e melhoria contínua da linguagem.

O que é uma API?

Quando você está em um restaurante e faz um pedido ao garçom, você não precisa saber como a comida é preparada. O garçom leva seu pedido à cozinha e depois traz a comida pronta. Da mesma forma, uma API atua como intermediária entre diferentes sistemas, levando suas solicitações para o backend e retornando os dados ou serviços solicitados. Assim, APIs nos servem informações valiosas sem que precisemos nos preocupar com os processos internos.

Essa flexibilidade da API é extremamente versátil. Uma mesma API pode ser disponibilizada para sistemas Desktop, Web e até Mobile.

Ou seja, uma API (Interface de Programação de Aplicações) é um conjunto de definições e protocolos que permite que diferentes softwares se comuniquem entre si. Em termos técnicos, uma API especifica os métodos e os formatos que os desenvolvedores podem usar para interagir com o sistema, facilitando a troca de informações e a execução de funcionalidades específicas sem expor a lógica interna do sistema.

APIs utilizam protocolos de comunicação padrão, como HTTP/HTTPS 𓆉 , e podem trabalhar com diversos formatos de dados, como JSON 𓆉. Elas definem endpoints, que são pontos de acesso específicos onde as solicitações podem ser feitas e as respostas podem ser recebidas. Dessa forma, APIs proporcionam uma interface segura e eficiente para acessar recursos e funcionalidades de aplicações, promovendo a integração entre diferentes sistemas e serviços.

Fluxo genérico de uma API

Na imagem, percebemos que o Client — dispositivos como computador, notebook ou celular — são nosso pronto de entrada. Quando acessamos, por exemplo, o Instagram, realizamos uma requisição para a API responsável (ênfase no segundo bloco da imagem), que se comunicará com o servidor para nos retornar alguma informação. Esse retorno será realizado em JSON, XML ou qualquer outro formato de resposta. Essa requisição é realizada via protocolo HTTP e a resposta é interpretada pela linguagem de programação responsável pela geração de interfaces (UI).

O que é Protocolo HTTP?

O HTTP (Hypertext Transfer Protocol) é um protocolo de comunicação fundamental na web, utilizado para a troca de informações entre clientes e servidores. Ele é a base para a transmissão de dados na web e permite que navegadores, servidores e outros aplicativos web se comuniquem.

O protoclo HTTP define vários métodos de requisição que especificam a ação desejada.

  • GET: Solicita dados de um recurso.
  • POST: Envia dados para um servidor, geralmente para criar ou atualizar um recurso.
  • PUT: Substitui ou atualiza um recurso existente.
  • DELETE: Remove um recurso.

Quando um cliente faz uma solicitação HTTP, ele envia um "request" (requisição) que inclui o método HTTP, a URL do recurso, e os cabeçalhos necessários. O servidor responde com um "response" (resposta) que inclui um código de status HTTP 𓆉, cabeçalhos e, se aplicável, o corpo da resposta com os dados solicitados.

Essa resposta, como dito anteriormente, pode possuir qualquer formato. Trataremos nesse artigo o formato JSON.

JSON

O JSON (JavaScript Object Notation) é um formato leve para troca de dados, amplamente utilizado para enviar e receber informações entre clientes e servidores. Em termos técnicos, JSON é uma forma estruturada de representar dados em texto, que é fácil de ler e escrever para humanos e simples de analisar e gerar para máquinas.

{
  "nome": "João",
  "idade": 30,
  "casado": true,
  "endereços": [
    {
      "rua": "Rua A",
      "cidade": "Cidade X"
    },
    {
      "rua": "Rua B",
      "cidade": "Cidade Y"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

JSON usa uma sintaxe baseada em pares chave-valor e arrays, o que o torna muito eficiente para representar dados estruturados. Os dados são organizados em objetos e arrays, permitindo uma representação clara e direta das informações.

HTTP Código de Resposta (Status Code)

Quando recebemos uma resposta de uma API, precisamos enviar uma resposta para o cliente sobre o status da requisição.

O status code é de extrema importância para a resposta de uma API. É a partir dele que o cliente (seja ele um aplicativo web, mobile ou desktop) lidará com a sua interação em suas interfaces. Esses queridos códigos possuem a responsabilidade de comunicar a resposta a partir de códigos que variam de 100 a 599. Alguns códigos são extremamente conhecidos, até por leigos que não entendem de programação, como, por exemplo, o erro 404 Not Found.

Alguns dos códigos de respostas mais conhecidos são:

200 OK: A requisição foi bem-sucedida. Esta é a resposta padrão para requisições HTTP bem-sucedidas.

201 Created: A requisição foi bem-sucedida e um novo recurso foi criado como resultado. Esta é a resposta enviada após uma requisição POST.

204 No Content: A requisição foi bem-sucedida, mas não há conteúdo para enviar de volta. É comum em respostas para requisições DELETE.

400 Bad Request: A requisição não pôde ser processada devido a um erro no cliente, como parâmetros inválidos ou dados incorretos.

401 Unauthorized: A requisição requer autenticação do usuário. Esta resposta é enviada quando a autenticação é necessária e falhou ou ainda não foi fornecida.

404 Not Found: O servidor não encontrou o recurso solicitado. Este código é frequentemente retornado quando o recurso não existe ou a URL está incorreta.

500 Internal Server Error: O servidor encontrou uma situação que não sabe como lidar. É uma resposta genérica para quando um erro inesperado ocorre no servidor.

Clique aqui caso tenha interesse em conhecer mais códigos do Status Code.

Desenvolvendo a API DessaVezEuNãoEsqueço

GitHub logo yagopeixinho / DessaVezEuNaoEsquecoAPI

DessaVezEuNaoEsquecoAPI, desenvolvida em .NET 8.0 & C#, é a sua solução definitiva para garantir que você nunca mais esqueça de nada! Seja uma lista de compras, tarefas diárias, itens para uma viagem ou qualquer outra coisa importante, essa API oferece uma interface simples e intuitiva para gerenciar suas listas e lembretes de maneira eficiente.

Uma Introdução ao Essencial com Entity Framework e SQLite.

IntroduçãoContatoLicença

Introdução

Desenvolva a API DessaVezEuNaoEsqueco. No meio desse desenvolvimento, vamos mergulhar nos conceitos do .NET e API.

Fundamentos Essenciais para Web APIs com .NET: Uma Introdução à Propedêutica (corpo de ensinamentos introdutórios ou básicos de uma disciplina; ciência preliminar, introdução.) com Entity Framework e SQLite. Entenda os conceitos por trás de uma Web API utilizando o .NET 8.0 e o Entity Framework Core.

Esse artigo é destinado para todos os níveis de programadores, desde os menos experientes até os mais avançados. Nosso objetivo é compreender o que acontece por trás dos panos e nutrir alguns conhecimentos acerca de uma API (Application Programming Interface) e seus comportamentos.

Sumário:

  • Compreendendo .NET & C#
  • Entendendo o que é uma API
    • Protocolo HTTP
    • JSON
    • HTTP Código de Resposta (Status Code)
  • Criação do projeto DessaVezEuNaoEsquecoAPI
    • Sobre o Projeto
    • Instalação
      • Ubuntu




Sobre o Projeto

DessaVezEuNaoEsquecoAPI é uma solução desenvolvida em .NET 8.0 e C# para garantir que você nunca mais esqueça de nada. Se você precisa gerenciar uma lista de compras, tarefas diárias, itens para uma viagem ou qualquer outra coisa importante, esta API oferece uma interface simples e intuitiva para manter suas listas e lembretes organizados de maneira eficiente.

O objetivo deste projeto é explorar conceitos fundamentais do .NET e C#, além de suas principais dependências. Nosso foco principal é entender os princípios básicos e iniciais do .NET e suas responsabilidades.

Embora seja um projeto de nível iniciante, ele é excelente para desenvolvedores que desejam aprender os fundamentos do .NET ou se familiarizar com o desenvolvimento de aplicações nesta plataforma.

Vamos instalar as nossas ferramentas necessárias para termos o ambiente perfeito.

Ubuntu

Perfeito! Então você é adepto ao clube do penguim!

Organize seu ambiente e vamos começar.

Tecnologias utilizadas

  • .NET
  • Entity Framework Core
  • SQLite
  • Visualizador de Banco de dados da sua preferência (recomendo o DBrowser pelo forte suporte ao SQLite)
  • Um IDE de sua preferência (Recomendo o JetBrains Rider ou Visual Studio Code)

Banco de dados

Utilizaremos o SQLite como o banco de dados principal. O SQLite é um banco de dados local que armazena informações em um único arquivo em sua própria máquina. Esta escolha visa simplificar a visualização e o desenvolvimento inicial da API, reduzindo o nível de abstração e tornando o processo mais produtivo. Ao optar pelo SQLite, evitamos a necessidade de instalações complexas e desnecessárias, o que facilita a configuração e o gerenciamento do banco de dados durante as fases iniciais do projeto.

Vamos começar instalando nossas ferramentas no Ubuntu?

1 - Atualize os pacotes do sistema

  sudo apt-get update
  sudo apt-get upgrade
Enter fullscreen mode Exit fullscreen mode

2 - Instale o .NET SDK:

  wget https://packages.microsoft.com/config/ubuntu/20.04/packages-      
  microsoft-prod.deb -O packages-microsoft-prod.deb
  sudo dpkg -i packages-microsoft-prod.deb
  sudo apt-get update
  sudo apt-get install -y dotnet-sdk-8
Enter fullscreen mode Exit fullscreen mode

3 - Instale o SQLite:

  sudo apt-get install -y sqlite3
Enter fullscreen mode Exit fullscreen mode

4 - Instale o DB Browser for SQLite:

sudo apt-get install -y sqlitebrowser
Enter fullscreen mode Exit fullscreen mode

5 - Instale o JetBrains Rider ou a IDE de sua preferência:

Hello, .NET no Ubuntu

Com todas as tecnologias instaladas em sua máquina, estamos prontos para por a mão na massa e dar iniciao oo projeto Dessa Vez Eu não Esqueço.

1 - Com o SDK instalado, você pode criar um novo projeto Web API usando o comando:

dotnet new webapi -n DessaVezEuNaoEsquecoAPI
Enter fullscreen mode Exit fullscreen mode

2 - Restaurar pacotes e construir o projeto:

dotnet restore
dotnet build
Enter fullscreen mode Exit fullscreen mode

3 - Executar projeto e verificar se está tudo corretamente

dotnet run
Enter fullscreen mode Exit fullscreen mode

O projeto será iniciado, e você pode acessar a API em http://localhost:5000 (ou o URL exibido no terminal).

Windows

Perfeito! Então você é um entusiasta do Windows!

Organize seu ambiente e vamos começar.

Tecnologias utilizadas

  • .NET
  • Entity Framework Core
  • SQLite
  • Visualizador de Banco de dados da sua preferência (recomendo o DB Browser pelo forte suporte ao SQLite)
  • Uma IDE de sua preferência (Recomendo o Visual Studio Community ou Visual Studio Code)

Banco de dados

Utilizaremos o SQLite como o banco de dados principal. O SQLite é um banco de dados local que armazena informações em um único arquivo em sua própria máquina. Esta escolha visa simplificar a visualização e o desenvolvimento inicial da API, reduzindo o nível de abstração e tornando o processo mais produtivo. Ao optar pelo SQLite, evitamos a necessidade de instalações complexas e desnecessárias, o que facilita a configuração e o gerenciamento do banco de dados durante as fases iniciais do projeto.

Vamos começar instalando nossas ferramentas no Windows?

  1. Atualize o sistema

    • Verifique se há atualizações disponíveis para o Windows e instale-as.
  2. Instale o .NET SDK:

    • Acesse a página de downloads do .NET e baixe o instalador do SDK para a versão desejada (por exemplo, .NET 8).
    • Execute o instalador e siga as instruções para concluir a instalação.
  3. Instale o DB Browser:

  4. Instale o Visual Studio Community ou a IDE de sua preferência:

Hello, .NET no Windows

Com todas as tecnologias instaladas em sua máquina, estamos prontos para colocar a mão na massa e dar início ao projeto Dessa Vez Eu Não Esqueço.

1 - Crie um novo projeto Web API usando o SDK:

  • Abra o Prompt de Comando ou o PowerShell e execute o comando:
dotnet new webapi -n DessaVezEuNaoEsquecoAPI
Enter fullscreen mode Exit fullscreen mode

2 - Restaurar pacotes e construir o projeto:

  • Navegue até o diretório do projeto
cd DessaVezEuNaoEsquecoAPI
Enter fullscreen mode Exit fullscreen mode

Rode os comandos:

dotnet restore
dotnet build
Enter fullscreen mode Exit fullscreen mode

3 - Executar o projeto e verificar se está tudo correto:

  • Rode o comando:
dotnet run
Enter fullscreen mode Exit fullscreen mode
  • O projeto será iniciado, e você pode acessar a API em http://localhost:5000 (ou o URL exibido no terminal).

Pit-Stop sobre estrutura inicial do projeto.

☕︎ Ao inicializar o projeto, vamos nos deparar em uma aplicação típica em .NET core para desenvolvimento web. Essa estrutura de arquivos iniciais pode variar a depender dano forma que você criou a sua aplicação.

Entendendo os arquivos iniciais do .NET Core

Ao abrir o seu editor de texto, você provavelmente se deparofu com uma sequência de arquivos (os quais você não faz a mínima ideia, caso seja seus primeirso contatos com o .NET).

Nosso objetivo antes de colocar a mão no código é compreender as responsabilidade de cada arquivo e entender suas respectivas funcionalidades.

Program.cs

O arquivo Program.cs é o arquivo de entrada da aplicação principal e é extremamente comum em aplicações web com o .NET.

Este arquivo é essencial para configurar a infraestrutura básica da sua aplicação e gerenciar como as requisições HTTP são tratadas.

  • Ponto de Entrada

    • O arquivo Program.cs é o ponto de entrada da aplicação. Nesse arquivo o Host da aplicação é configurado e construído.
  • Modelo Simplificado

    • A partir do .NET 6, o modelo de hospedagem foi simplificado, que combina o arquivo Startup.cs e Program.cs em um unico arquivo — geralmente o Program.cs (Ressalto isto, pois, em algumas aplicações com versões inferiores ao .NET 6, não existirá o arquivo Startup.cs).
  • Configurações, Middlewares e Endpoints

    • No Program.cs, você configura serviços, middlewares e endpoints. Serviços são adicionados ao contêiner de dependências, middlewares.

appsettings.json

O appsettings.json é o arquivo de configuração utilizado para armazenar configurações da aplicação, como strings de conexão, configurações de logging, e outros parâmetros de configuração.

  • Pode haver vários arquivos de configuração para diferentes ambientes (ex: appsettings.Development.json, appsettings.Production.json).

Dependencies

De forma objetiva, esse é o arquivo que contém a nossa lista de dependências e pacotes NuGet 𓆉 que o projeto utiliza.

Entendendo as Entidades (Models)

Se você já possui alguma experiência prévia, é provável que já tenha ouvido muito o termo "Entidade". Se não, não se preocupe. Entidades não são seres espirituais nem nada que vá nos fazer mal (apesar de algumas controvérsias). :D

Em .NET, especialmente no contexto do Entity Framework 𓆉︎ e outros ORMs 𓆉︎ (Object-Relational Mappers), as entidades referem-se às classes que representam os objetos principais do seu domínio de aplicação. Elas são usadas para modelar e interagir com os dados armazenados em um banco de dados relacional.

Basicamente o Entity Framework converte nossas classes em tabelas no banco de dados. Cada entidade corresponde a uma tabela. Por exemplo, se criarmos a classe "User", o Entity Framework transformará essa classe em uma tabela chamada "Users" no banco de dados.

Características de Entidades em .NET

  • Representação de Objetos de Domínio: As entidades são tipicamente usadas para representar objetos de negócio ou entidades do mundo real, como um Usuário, Produto, Pedido, etc.

  • Mapeamento para o Banco de Dados: As propriedades das entidades geralmente correspondem aos campos das tabelas do banco de dados. O ORM, como o Entity Framework, mapeia automaticamente essas entidades para as tabelas do banco de dados.

  • Comportamentos e Regras de Negócio: Além de simplesmente armazenar dados, as entidades também podem incluir lógica de validação, regras de negócio e métodos que operam sobre esses dados.

  • Relacionamentos: Entidades podem ter relacionamentos uns com os outros (por exemplo, um Pedido pode estar associado a vários Itens de Pedido), o que é definido nas classes de entidade através de propriedades de navegação.

Embora as entidades sejam frequentemente associadas ao uso do Entity Framework ou outras ORMs para o mapeamento de banco de dados relacionais, elas não são usos exclusivos dessas ferramentas.

Entidades em .NET, no contexto mais amplo do desenvolvimento de software, são simplesmente classes que representam objetos de domínio ou entidade de negócio.

Agora que você sabe o que é uma entidade, vamos desenvolver a entidade do nosso projeto?

Criando Nossa Primeira Entidade

  • Inserindo diretório e classe
    • No diretório da nossa aplicação, insira uma nova pasta chamada Models.
    • Dentro dessa pasta, insira um outro diretório chamado Atividade.cs com a seguinte codificação.
namespace DessaVezEuNaoEsquecoAPI.Models;

using System.ComponentModel.DataAnnotations;

public class Atividade
{
    // Propriedade que representa o identificador único da atividade
    public int Id { get; set; }

    // Propriedade que representa o nome da atividade.
    public required string Nome { get; set; } // Nome da nossa atividade que não deve ser esquecida.

    // Propriedade que representa a data em que a atividade deve ser realizada
    public DateTime Data { get; set; } // Data de realizar a atividade.
}
Enter fullscreen mode Exit fullscreen mode

Arquivo Atividade.cs em Model/Atividade.cs
Código completo do bloco de Atividade

Clique aqui para ver no Github

Inserimos nossa primeira Entidade no sistema. E agora? Como usamos? Pra que utilizamos? Afinal, qual o impacto que ela terá no sistema?

Para responder essas perguntas, precisamos entender sobre o Entity Framework.

Entendendo e o que é uma ORM & Entity Framework Core

O Entity Framework (EF) em .NET é uma ORM (Object-Relation Mapping), que faciltia o mapeamento de estrutura de dados em um banco de dados relacionado para objetos em código .NET. Opaaaaaa. Talvez tenha ficado um pouco complexo! Vamos simplificar?

Uma ORM é como um “tradutor” que ajuda o computador a entender duas coisas diferentes que não falam a mesma lingua.

Quando criamos um programa que precisa armanezar e recuperar informações de um banco de dados, geralmente utilizamos linguagem de programação como C#, Java ou Python. Os bancos de dados, por outro lado, armazenam esses dados de uma forma diferente, geralmente em tabelas e colunas.

A ORM atua como ponte entre dois mundos. Ela permite que os programadores usem objetos (como classes em C#) para representar dados do banco de dados. Em vez de lidar diretamente com comando SQL (linguagem utilizada para trabalhar com banco de dados), a ORM traduz automaticamente todas as operações do programa em comandos SQL que o banco de dados entende. É como um assistente que traduz as instruções que você dá em um idioma (objetos do seu programa) para outro idioma (comandos SQL do banco de dados) e vice-versa, tornando o desenvolvimento de software mais eficiente e menos propenso a erros.

O Entity Framework é uma ORM que usamos para trabalhar com no ecossistema .NET. Diferentes tecnologias possuem diferentes ORMS com especificações prórpias e diferentes tecnologias possuem mais de uma ORM a sua disposição.

Algumas ORMs para diferentes linguagens

  • Python: SQLAlchemy, Django ORM (para aplicações Django), Peewee, PonyORM.
  • Java: Hibernate (provavelmente o mais conhecido), EclipseLink, MyBatis, jOOQ (focado em SQL fluent).
  • Node.js: Sequelize (para bancos de dados relacionais), Mongoose (para bancos de dados NoSQL como MongoDB), TypeORM (também suporta TypeScript).
  • C#: Entity Framework (EF Core para .NET Core e .NET 5+), Dapper (mais orientado a SQL puro), NHibernate (inspirado no Hibernate para Java).

Data Annotations na nossa Entidade com o Entity Framework

O Data Annotations são atributos que você pode aplicar a propriedades de classes no Entity Framework para configurar o mapeamento de banco de dados e o comportamento de validação. Eles são parte do namespace 𓆉 System.ComponentModel.DataAnnotations e oferecem uma maneira fácil e declarativa de definir metadados diretamente no código.

Agora que entendemos a necessidade da nossa ORM (EF), vamos mapear nossa Entidade Atividade para receber algumas propriedades.

  • Inserindo Data Annotations na nossa Entidade
    • Vamos acessar o arquivo Atividade.cs e inserir os seguintes atributos acima da nossa propriedade Nome.
      • StringLength(50)
      • Required
namespace DessaVezEuNaoEsquecoAPI.Models;

using System.ComponentModel.DataAnnotations;

public class Atividade
{
    // Propriedade que representa o identificador único da atividade
    public int Id { get; set; }

    // Propriedade que representa o nome da atividade.
    // Atributo StringLength define um tamanho máximo de 50 caracteres.
    // Atributo Required indica que o campo é obrigatório.
    [StringLength(50)]
    [Required]
    public required string Nome { get; set; } // Nome da nossa atividade que            não deve ser esquecida.

    // Propriedade que representa a data em que a atividade deve ser realizada
    public DateTime Data { get; set; } // Data de realizar a atividade.
}
Enter fullscreen mode Exit fullscreen mode

Arquivo Atividade.cs com incrementação do Data Annotation:
Imagem do bloco de código após implementação do Data Annotation

Clique aqui para ver no Github.

No código fornecido, você pode perceber que insiremos as propriedades [Required] e StringLength(50).

Como o nome exemplifica, o Required determina que um campo é obrigatório e o StringLength determina a quantidade de caracteres que a propriedade deve ter.

Essas características dos Data Annotations podem ser utilizadas para definir restrições diretamente nas entidades. Ajudam a manter o código limpo e legível, enquanto definem comportamentos específicos para suas propriedades no contexto do Entity Framework.

Existe uma GAAAAAAMA de possibilidades de utilizar o Data Annotations. Clique aqui para se aprofundar nesse universo.

Instalando o Entity Framework

Agora que sabemos o que é uma ORM e a responsabilidade do Entity Framework em uma aplicação .NET, vamos, finalmente, inserir o Entity Framework no nosso projeto para que consigamos realizar manipulações no nosso banco de dados.

Compreendendo o que é NuGet

Os pacotes NuGet são unidades de distribuição de código para o ecossistema .NET. São usados para empacotar bibliotecas, frameworks e ferramentas que podem ser facilmente intregados em projetos .NET.

Cada pacote NuGet contém arquivos necessários para sua instalação e utilização. A principal vantagem é que simplificam o gerenciamento de dependências e permitem que os desenvolvedores compartilhem e reutilizem código de forma eficiente dentro do projeto.

O NuGet é similar ao npm do Node e ao pip do Python.

Para utilizarmos o Entity Framework com o SQLite em uma aplicação .NET, vamos realizar a sua implementação no nosso Pacote NuGet.

Instalando o Pacote Nuget do Entity Framework

  1. Instalação dos Pacotes NuGet
    • Abra o Console de Gerenciador de Pacotes NuGet na sua respectiva IDE.
    • Execute os seguintes comandos para instalar os pacotes necessários:
Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Microsoft.EntityFrameworkCore.Sqlite
Enter fullscreen mode Exit fullscreen mode

Esse comando pode variar a depender do seu terminal, sistema operacional ou IDE. Pelo visual Studio Code, você pode utilizar o comando dotnet add package Microsoft.EntityFrameworkCore.Sqlite e dotnet add package Microsoft.EntityFrameworkCore.Design

Ao rodar esse comando, sua aplicação .NET já está pronta para conseguirmos utilizar o Entity Framework.

Configurando o Entity Framework em nosso ambiente

  1. Configurações do Contexto do Banco de Dados.
    • Crie uma classe que herde DbContext para representar o seu banco de dados e configurar as entidades.

Lembra que falamos disso um pouco mais cedo quando explicamos ORM? Nesse momento em que vamos inserir o DbContext e as nossas entidades (Models) vão começar a representar itens no nosso banco de dados.

Vamos criar um diretório chamado Data na raiz do nosso projeto, o qual, vamos inserir um arquivo chamado DessaVezEuNaoEsquecoContext.cs dentro dele. Esse arquivo é responsável por essa nossa classe que fará a conexão com o nosos Entity Framework.

using  DessaVezEuNaoEsquecoAPI.Models; // Importa o namespace onde o modelo Atividade está definido.
using  Microsoft.EntityFrameworkCore; // Importa o namespace necessário para usar o Entity Framework Core.

namespace  DessaVezEuNaoEsquecoAPI.Data;

public  class  DessaVezEuNaoEsquecoContext : DbContext
{
    // Construtor que aceita opções de configuração para o contexto e passa essas opções para o construtor base da classe DbContext.

    public DessaVezEuNaoEsquecoContext(DbContextOptions<DessaVezEuNaoEsquecoContext> options)
    : base(options)
    {
    }

    // Propriedade DbSet que representa a coleção de Atividades na base de dados.
    public  DbSet<Atividade> Atividades { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Arquivo DessaVezEuNaoEsquecoContext.cs em Data/DessaVezEuNaoEsquecoContext.cs

Bloco de código com a imagem do Contexto da Aplicação

Clique aqui para ver no Github.

Com esse código inserido, o nosso contexto já está apto a compreender os nossos dados. Entretanto, ainda precisamos comunicar ao nosso programa qual banco de dados que vai ser utilizado — Vale ressaltar que diferentes bancos de dados possuem diferentes tipos de configurações.

Configurar o Contexto do Banco de Dados no arquivo Program.cs

  1. Inserir o nosso Contexto do banco de dados.
    • Ao entrar no arquivo Program.cs, vamos inserir o nosso Contexto do banco de dados no nosso programa.
// Configuração do banco de dados
builder.Services.AddDbContext<DessaVezEuNaoEsquecoContext>(options => options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection")));
Enter fullscreen mode Exit fullscreen mode

Se você instalou o .NET com o comando dotnet new webapi -n DessaVezEuNaoEsquecoAPI, seu arquivo Program.cs deve estar similar a esse arquivo:

Imagem do exemplo da estrutura inicial do .NET

Esse arquivo nesse modelo é o padrão da aplicação (podendo conter variações a depender da versão). Nele temos uma aplicação que irá nos retornar a temperatura. Mas não é isso que queremos.

Vamos realizar uma limpeza nele, removendo todos os itens que não vão interessar ao nosso projeto.

using DessaVezEuNaoEsquecoAPI.Data;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "DessaVezEuNaoEsqueco API", Version = "v1" });
});

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var  app  =  builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.Run();
Enter fullscreen mode Exit fullscreen mode

As modificações realizadas nesse código consistem na remoção do código predefinido e a inserção da nossa conexão com o SQLite.

  • Adição do Banco de Dados: builder.Services.AddDbContext<DessaVezEuNaoEsquecoContext>(options => options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection")));
    • O código atual introduz a configuração do banco de dados SQLite, o que permite à aplicação persistir dados de maneira mais robusta com o Entity Framework

Essa linha de código configura o contexto do Entity Framework Core (DessaVezEuNaoEsquecoContext) para usar um banco de dados SQLite com a string de conexão definida na configuração da aplicação.

A função GetConnectionString é responsável por trazer a nossa comunicação com o banco de dados. O valor passado por parâmetro “DefaultConnection” ainda não foi definido, então caso você tente rodar o projeto, provavelmente você receberá um erro.

A função GetConnectionString irá buscar no arquivo appsettings.json a propriedade DefaultConnection.

Para nossa conexão estar completa, precisamos acessar o arquivo appsettings.json 𓆉 e inserir o a nossa propriedade:

"ConnectionStrings": {
    "DefaultConnection": "Data Source=DessaVezEuNaoEsquecoDb.db"
}
Enter fullscreen mode Exit fullscreen mode

Arquivo appsettings.json em appsettings.json na raíz do projeto:
Bloco de código do appsettings.json

Clique aqui para ver no Github.

A propridade no JSON DefaultConnection é responsável por realizar a nossa conexão com o banco de dados. Em bancos mais complexos que precisem de autenticação, essa DefaultConnection pode variar, como o SQLServer, MySQL ou PostgreSQL.

Pit-stop Arquivo AppSettings.json

☕︎ O arquivo appsettings.json é um arquivo de configuração usado para armazenar configurações de forma estruturada em formato JSON. Ele permite que você defina valores de configuração que podem ser facilmente acessados e usados em toda a aplicação, como strings de conexão com bancos de dados, configurações de logging, chaves de API, e outras opções de configuração. No nosso caso, utilizamos para realizar a nossa conexão com o SQLite.

Seu projeto agora deve ser capaz de realizar comunicações com o Entity Framework.

O pacote já está configurado corretamente na sua máquina e você não precisará mais utilizar o SQL nativo para realizar operações com o banco de dados.

Migração de Banco de Dados

Se você já está familiarizado com ORMs, provavelmente você também estará familiarizado com o que são migrações de bancos de dados.
Se você não está familiarizado, vamos te "familiarizar" agora!

Imagine que você está construindo uma cidade (sua aplicação) e que precisa de um mapa (o banco de dados) para saber onde cada prédio (tabela) deve ser colocado. No início, seu mapa pode ser simples: apenas algumas ruas e alguns prédios. Mas à medida que sua cidade cresce, você precisa adicionar novos bairros, talvez uma escola aqui, um parque ali, ou até mesmo reconfigurar algumas ruas para melhorar o tráfego. Essas mudanças são necessárias para que a cidade continue a funcionar bem e atenda às novas necessidades dos seus habitantes (usuários).

No contexto de banco de dados, as migrações funcionam da mesma forma. À medida que sua aplicação evolui, você pode precisar adicionar novas tabelas, alterar colunas existentes ou modificar a estrutura dos dados. O Entity Framework facilita essas mudanças, aplicando migrações que transformam automaticamente a estrutura do banco de dados para refletir as mudanças no seu código.

Migração com o Entity Framework

  1. No Console do Gerenciador de Pacotes NuGet, execute o seguinte comando:
dotnet ef migrations add CriacaoEntidadeAtividade
Enter fullscreen mode Exit fullscreen mode

Você precisar ter o dotnet tool instalado globalmente. Rode o comando dotnet tool install --global dotnet-ef

Esse comando executa nosso comando de adicionar uma migração. Ele mapeia as nossas Entidades (o Model que criamos mais cedo chamado Atividades.cs, lembra?) e insere corretamente no mapeamento do nosso banco de dados.

Deve ser criado uma pasta na raíz do seu projeto chamado Migrations com essa atualização.

Agora que realizamos essa funcionalidade do banco de dados com as nossas modificações — Referente a criação do Modelo Atividades, precisamos atualizar o nosso banco para que possamos visualizar as modificações.

  1. No Console do Gerenciador de Pacotes NuGet, execute o seguinte comando:
dotnet ef database update
Enter fullscreen mode Exit fullscreen mode
  1. Visualização do Banco de Dados pelo DB Browser
    • Abra o DB Browser e clique em Open Database. Selecione o arquivo que foi gerado após o comando dotnet ef update-database (DessaVezEuNaoEsquecoDb.db).

Imagem 1 do DB Browser após migração

Você agora é capaz de realizar as modificações que foram realizadas diretamente no código em C#.

Imagem 2 do DB Browser após migração

Esse é o poder de uma ORM e é com essa ferramenta poderosa que desenvolvedores conseguem produzir absolutamente mais.

Controllers

Os Controllers são extremamente importantes para a nossa aplicação.

Em uma aplicação Web API, os controllers desempenham um papel central na exposição de endpoints que permitem a interação com dados através de solicitações HTTP, como GET, POST, PUT e DELETE. Aqui estão os principais aspectos e funcionalidades dos controllers em uma Web API utilizando .NET.

Falamos mais cedo sobre Protocolo HTTP mas vamos relembrar?
O protocolo HTTP é um conjunto de regras que define como informações são transmitidas na internet. Funciona como um mensageiro entre clientes (como um navegador) e servidores (que armazenam sites e dados). O HTTP permite solicitar e receber informações, como páginas da web e dados de aplicativos.

Criando Nossos Controllers

Só isso não basta para que possamos realizar requisições em nosso ambiente local. Vamos utilizar uma interface conhecida como Swagger para nos auxiliar na visualização das requisições.

O Swagger é uma ferramenta que ajuda desenvolvedores a criar, documentar e testar APIs. Ele cria uma página web onde você pode ver todas as rotas da API, os parâmetros que elas aceitam, e até testar as requisições diretamente na página. Isso facilita a comunicação entre desenvolvedores e torna mais fácil entender e usar a API.

Existem outras formas de realizarmos esse tipo de requisição via protocolo HTTP como o Postman, Insominia ou até mesmo diretamente pelo CURL. Entretanto, nesse artigo, como dito anteriormente, vamos focar no uso do mínimo de ferramentas possíveis para evitarmos abstrações.

Antes de aprofundarmos mais na criação dos nossos Controllers, eu disponibilizei o código dessa aplicação no GitHub.

O código está comentando e pode conter mais detalhes e informações.

GitHub logo yagopeixinho / DessaVezEuNaoEsquecoAPI

DessaVezEuNaoEsquecoAPI, desenvolvida em .NET 8.0 & C#, é a sua solução definitiva para garantir que você nunca mais esqueça de nada! Seja uma lista de compras, tarefas diárias, itens para uma viagem ou qualquer outra coisa importante, essa API oferece uma interface simples e intuitiva para gerenciar suas listas e lembretes de maneira eficiente.

Uma Introdução ao Essencial com Entity Framework e SQLite.

IntroduçãoContatoLicença

Introdução

Desenvolva a API DessaVezEuNaoEsqueco. No meio desse desenvolvimento, vamos mergulhar nos conceitos do .NET e API.

Fundamentos Essenciais para Web APIs com .NET: Uma Introdução à Propedêutica (corpo de ensinamentos introdutórios ou básicos de uma disciplina; ciência preliminar, introdução.) com Entity Framework e SQLite. Entenda os conceitos por trás de uma Web API utilizando o .NET 8.0 e o Entity Framework Core.

Esse artigo é destinado para todos os níveis de programadores, desde os menos experientes até os mais avançados. Nosso objetivo é compreender o que acontece por trás dos panos e nutrir alguns conhecimentos acerca de uma API (Application Programming Interface) e seus comportamentos.

Sumário:

  • Compreendendo .NET & C#
  • Entendendo o que é uma API
    • Protocolo HTTP
    • JSON
    • HTTP Código de Resposta (Status Code)
  • Criação do projeto DessaVezEuNaoEsquecoAPI
    • Sobre o Projeto
    • Instalação
      • Ubuntu




Configurando Swagger para realizarmos solicitações HTTP

No seu arquivo Program.cs insira o seguinte código:

using  Microsoft.OpenApi.Models;

builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "DessaVezEuNaoEsqueco API", Version = "v1" });
});

// Adicionar serviço de controllers
builder.Services.AddControllers();

// Middleware de desenvolvimento para Swagger 
if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Minha API v1"); }); }

// Define os endpoints da API 
app.MapControllers();
Enter fullscreen mode Exit fullscreen mode

Arquivo Program.cs na raíz do projeto após a implementação do Swagger:
Imagem da implementação do Swagger

Clique aqui para ver no Github.

Agora nosso código consegue enteder o Swagger e é capaz de realizar requisições.

  • Adição do Serviço de Controllers:
    • Foi adicionado builder.Services.AddControllers(); dentro do método ConfigureServices(). Esse serviço é necessário para que a aplicação reconheça e configure os controllers que você define na sua aplicação Web API (no nosso caso, o AtividadesController).
  • Mapeamento de Controllers:
    • Mantido app.MapControllers(); para assegurar que todos os controllers definidos na aplicação sejam mapeados corretamente.

Com as configurações do Swagger implementadas, podemos prosseguir com o desenvolvimento dos nossos Controllers.

Criando arquivo AtividadesController.cs

  • Crie um arquivo no diretório do seu projeto chamado Controllers e dentro desse diretório crie um arquivo de classe chamado AtividadesController.

E então, afinal, você me questiona... O que é um Controller e quais as suas responsabilidades? Um Controller em uma API gerencia as requisições HTTP, processa dados e retorna respostas. Ele mapeia endpoints para métodos que executam ações como criar, ler, atualizar e deletar dados. Ele é responsável pelo contato inicial com a API e saberá lidar com os dados e o que fazer.

O seu arquivo AtividadesController.cs deve estar similar ao meu código:

namespace DessaVezEuNaoEsquecoAPI.Controllers;

public class AtividadesController
{

}
Enter fullscreen mode Exit fullscreen mode

Aqui definimos a nossa classe Controller mas não implementamos absolutamente nenhum método. Vamos continuar codando?

Definindo o Método GET

  • Vamos desenvolver o nosso GET para recuperarmos todas as nossas atividades
    • O nosso método chamado GetAllAtividades é o nosso método por retornar todas as nossas atividades armazenadas no banco de dados.

Vamos inserir a codificação inicial para o nosso Controller e principalmente o nosso método GET:

using DessaVezEuNaoEsquecoAPI.Data; // Importa o namespace que contém a classe DessaVezEuNaoEsquecoContext, que é o contexto do Entity Framework Core usado para interagir com o banco de dados.
using DessaVezEuNaoEsquecoAPI.Models; // DessaVezEuNaoEsquecoAPI.Models: Importa o namespace que contém a classe Atividade, que é o modelo representando uma tabela no banco de dados.
using Microsoft.AspNetCore.Mvc; // Microsoft.AspNetCore.Mvc: Importa o namespace que contém tipos e classes para criar controladores e manipular requisições HTTP.
using Microsoft.EntityFrameworkCore; // Microsoft.EntityFrameworkCore: Importa o namespace que contém classes e métodos para trabalhar com o Entity Framework Core, uma ORM (Object-Relational Mapper) para .NET.

namespace DessaVezEuNaoEsquecoAPI.Controllers;

[ApiController]
[Route("api/[controller]")]
public class AtividadesController : ControllerBase
{
    private readonly DessaVezEuNaoEsquecoContext _context;

    public AtividadesController(DessaVezEuNaoEsquecoContext context)
    {
        _context = context;
    }

    // GET: api/atividades
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Atividade>>> GetAtividades()
    {
        return await _context.Atividades.ToListAsync();
    }
}
Enter fullscreen mode Exit fullscreen mode

Woooow... muita informação? Calma, Vamos passar por cada informação relevante durante a implementação do nosos controller. Recomendo que revisite o código quantas vezes sentir necessidade.

  • Using Statements
    O using statement é usado para incluir nossos namespaces, permitindo que você use classes e métodos definidos nesses namespaces sem precisar especificar o caminho completo. Isso simplifica o código e melhora a legibilidade. Inserimos os respectivos using no nosso código.

  • Atributos e ControllerBase

namespace DessaVezEuNaoEsquecoAPI.Controllers;

[ApiController]
[Route("api/[controller]")]
public class AtividadesController1 : ControllerBase

Enter fullscreen mode Exit fullscreen mode

Nota-se que foi implementado novos atributos: [ApiController], Route uma herança na classe AtividadesController.

  • ApiController: O atributo [ApiController] é usado para anotar uma classe como um controlador de API no .NET. Esse atributo oferece uma série de convenções e comportamentos automáticos que facilitam o desenvolvimento de APIs. Entre as funcionalidades fornecidas por [ApiController], incluem-se:

  • Route: O atributo [Route] é usado para definir a rota de acesso ao controlador e suas ações. O valor "api/[controller]" é um modelo de rota que define como as URLs serão mapeadas para este controlador. No caso específico "api/[controller]", [controller] é um placeholder que será substituído pelo nome do controlador, sem o sufixo "Controller". Por exemplo, se o nome da classe é AtividadesController, a rota será api/atividades.

  • ControllerBase: ControllerBase é a classe base para controladores em uma API. Ela fornece muitas das funcionalidades que são essenciais para criar controladores de API. A classe ControllerBase é uma versão mais leve da classe Controller e não inclui funcionalidades específicas para renderização de views (o que é apropriado para APIs RESTful). Algumas funcionalidades fornecidas por ControllerBase incluem:

  • Método GET

// GET: api/atividades
[HttpGet]
public async Task<ActionResult<IEnumerable<Atividade>>> GetAtividades()
{
    return await _context.Atividades.ToListAsync();
}
Enter fullscreen mode Exit fullscreen mode

Foi desenvolvido nessa codificação o método GetAtividades: Método assíncrono que retorna uma Task contendo um ActionResult com uma lista de objetos Atividade.

// GET: api/atividades
[HttpGet]
public async Task<ActionResult<IEnumerable<Atividade>>> GetAtividades()
{
    return await _context.Atividades.ToListAsync();
}
Enter fullscreen mode Exit fullscreen mode

Esse método busca todas as atividades do banco de dados de forma assíncrona e retorna a lista como resultado da requisição. O ToListAsync() é o método do próprio Entity Framework que nos retorna a listagem inteira de todas as atividades — Ressalto aqui o poder de uma ORM em uma aplicação.

Arquivo AtividadeController.cs em Controllers/AtividadesController.cs após implementação do método GET:
Bloco de código do GET no Controller

Clique aqui para ver no Github.

Com essas modificações, conseguimos agora realizar requisições GET para obter uma lista de todas as atividades armazenadas no banco de dados, utilizando o Entity Framework Core para interagir com o banco e retornando os dados no formato JSON por padrão.

Ao rodar o projeto, o Swagger nos retornará uma listagem vazia. Desenvolvemos o método que tratará para nós todas as atividades. Mas ainda não criamos o método para Criar essa atividades.

Retorno do GET do Swagger

Definindo o Método POST

  • Vamos desenvolver o nosso POST para sermos capazes de criar as nossas atividades
    • O nosso método chamado PostAtividade é o nosso método por criar as nossas atividades.

Vamos inserir a codificação no nosso Controller:

  // POST: api/atividades
    [HttpPost]
    public async Task<ActionResult<Atividade>> PostAtividade(Atividade atividade)
    {
        _context.Atividades.Add(atividade); // Adicionamos 
        await _context.SaveChangesAsync();

        return CreatedAtAction(nameof(GetAtividades), new { id = atividade.Id }, atividade);
    }
Enter fullscreen mode Exit fullscreen mode

Essa anotação indica que este método responde a uma solicitação HTTP POST. Geralmente, os métodos POST são usados para criar novos recursos no servidor.

  • Função Add em Atividades.Add

    • O Add é responsável por informar ao Entity Framework que novas informações estão sendo inseridas no nsso contexto. Nota-se, também, que na linha abaixo temos o método SaveChangesAsync, responsável por salvar essa informação no nosso banco de dados.
  • Função CreatedAtAction

    • O nosso retorno usa um método auxiliar que retorna um status HTTP 201 Created (lembra que falamos sobre Status Code mais cedo?)

Arquivo AtividadeController.cs em Controllers/AtividadesController.cs após implementação do método POST:
Bloco de código do método POST

Clique aqui para ver no Github.

Vamos realizar agora a tentativa de criar uma nova atividade pelo Swagger?

Imagem do Swagger no POST

Ao clicar no botão “Execute”, você deve ser capaz de visualizar a criação da nossa atividade.

Imagem de resposta do Swagger no método POST

Essa é a nossa resposta. O status code 200 sinaliza que a criação foi realizada com sucesso. Podemos visualizar agora que a nossa atividade “Limpar o Monitor” foi criada corretamente no nosso banco de dados.

Imagem da verificação do Swagger no método POST

Agora que somos capazes de listar todas as nossas atividades e também criar uma nova atividade.

Mas você me questiona: “Eu preciso procurar na minha gigantesca lista de itens que foram procastinados por uma atividade específica, como posso fazer isso?”.

Definindo o Método GET Individual

  • Vamos desenvolver o nosso GET Individual para sermos capazes de listar uma única atividade. Vamos realizar a busca ao banco de dados pelo ID.
    • O nosso método chamado GetAtividade é o nosso método responsável por recuperarmos uma atividade individual.

Vamos inserir a codificação no nosso Controller:

// GET: api/atividades/1
[HttpGet("{id}")]
public  async  Task<ActionResult<Atividade>> GetAtividade(int  id)
{
    // Procura uma atividade pelo ID fornecido.
    var  atividade  =  await  _context.Atividades.FindAsync(id);

    // Verifica se a atividade foi encontrada. Se não, retorna NotFound.
    if (atividade  ==  null)
    {
    return  NotFound();
    }

    return  atividade;
}
Enter fullscreen mode Exit fullscreen mode

Esse método é responsável por realizar o método FindAsync, do Entity Framework, que busca dentro do nosso banco de dados por alguma informação específica — No nosso caso, pelo id.

Além de realizar essa busca, ele também verifica se o valor é null, e caso seja, retornamos um método NotFound(), responsável por informar ao nosso Client que nenhuma informação daquele valor específico foi encontrado.

Arquivo AtividadeController.cs em Controllers/AtividadesController.cs após implementação do método GET por ID:
Bloco de código do GET Individual

Clique aqui para ver no Github.

Rode o projeto e, quando o Swagger inicializar, localize o método recém-criado. Insira um ID válido e um ID inválido para testar o nosso endpoint.

Imagem do Swagger testando o Endpoint

Ao clicar no botão "Execute", você deverá visualizar o retorno em JSON de algum item da lista.

Listagem do Swagger com a criação da atividade

Observe que a nossa Atividade "Limpar o Monitor" apareceu na listagem de itens recuperados.

Agora que conseguimos recuperar uma informação individual, precisamos ser capazes de editar essa informação.

Vamos definir o método PUT

  • Vamos desenvolver o nosso PUT para sermos capazes de realizar modificações por atividade
    • O nosso método chamado PutAtividade é o nosso método responsável por realizarmos edição em uma atividade já existente.

Vamos inserir a codificação no nosso Controller:


    // PUT: api/atividades/1
    [HttpPut("{id}")]
    public async Task<IActionResult> PutAtividade(int id, Atividade atividade)
    {
        // Verifica se o ID da URL é diferente do ID da atividade
        if (id != atividade.Id)
        {
            // Retorna um BadRequest (400) se os IDs não coincidirem
            return BadRequest();
        }

        // Atualiza o estado da atividade no contexto para Modified
        _context.Atividades.Update(atividade);

        try
        {
            // Salva as mudanças no banco de dados de forma assíncrona
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            // Se ocorrer uma exceção de concorrência, re-lança a exceção
            throw;
        }

        // Retorna NoContent (204) para indicar sucesso sem conteúdo no corpo da resposta
        return Ok(atividade);
    }
Enter fullscreen mode Exit fullscreen mode

Agora nossas ativiades podem ser alteradas. Vamos passar sobre algumas inserções no código?

  • Try & Catch
    • Bloco try: O código dentro do bloco try é executado normalmente. Se ocorrer uma exceção (erro) durante a execução desse código, o fluxo é interrompido e a exceção é lançada para o bloco catch.
try
{
    // Código que pode lançar uma exceção
}
Enter fullscreen mode Exit fullscreen mode
  • Bloco catch: O bloco catch captura a exceção lançada pelo bloco try. Aqui, você pode especificar um tipo de exceção específica ou usar um tipo genérico para capturar qualquer exceção. É o local ideal para tratar o erro ou registrar informações sobre ele.
catch (Exception ex)
{
    // Código para tratar a exceção
    Console.WriteLine($"Erro: {ex.Message}");
}
Enter fullscreen mode Exit fullscreen mode

Agora nossas ativiades podem ser alteradas. Vamos realizar nossas alterações pelo Swagger?

Vamos tentar agora atualizar a nossa Atividade “Limpar Monitor” para “Lavar Louça”. Para isso, rode o projeto e insira o id no método PUT.

No nosso body, inserimos a propriedade “nome” para “Lavar Louça”. Com todos os campos devidamente preenchidos, vamos clicar em “Execute”.

Imagem de inserir dados no POST via Swagger
Imagem de retorno de dados no POST via Swagger

Note que nossa resposta trouxe o ID 4, agora com o nome devidamente alterado. Se quiser, experimente executar outros métodos, como o GET, para visualizar a informação modificada. Você também pode usar o DB Browser para verificar as mudanças diretamente no banco de dados. Fique à vontade para explorar!

Arquivo AtividadeController.cs em Controllers/AtividadesController.cs após implementação do método PUT:
Bloco de código após implementação do método PUT

Clique aqui para ver no Github.

Suponhamos esta situação: "Eu inseri essa atividade, mas ela já foi feita por outra pessoa e agora preciso deletá-la do meu sistema." Para evitar esse tipo de problema no nosso projeto, vamos criar um método para deletar atividades que não são mais úteis.

Definindo o Método DELETE

  • Vamos desenvolver o nosso DELETE para sermos capazes de realizar modificações por atividade
    • O nosso método chamado DeleteAtividade é o nosso método responsável por realizarmos a deleção de uma atividade existente.

Vamos inserir a codificação no nosso Controller:

// DELETE: api/atividades/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteAtividade(int id)
{
    // Tenta encontrar a atividade com o ID fornecido no banco de dados
    var atividade = await _context.Atividades.FindAsync(id);

    // Verifica se a atividade não foi encontrada
    if (atividade == null)
    {
        // Retorna NotFound (404) se a atividade não existir
        return NotFound();
    }

    // Remove a atividade do contexto
    _context.Atividades.Remove(atividade);

    // Salva as mudanças no banco de dados de forma assíncrona
    await _context.SaveChangesAsync();

    // Retorna NoContent (204) para indicar sucesso sem conteúdo no corpo da resposta
    return NoContent();
}
Enter fullscreen mode Exit fullscreen mode

Esse código é responsável por realizar a remoção de atividades do nosso banco de dados.

  • Encontrar a Atividade:

    • await _context.Atividades.FindAsync(id) tenta localizar a atividade com o ID fornecido no banco de dados. Isso retorna a atividade se ela existir ou null se não for encontrada.
  • Verificação de Existência:

    • Se atividade for null, significa que não foi encontrada uma atividade com o ID fornecido. Retorna NotFound (404) para indicar que o recurso não foi encontrado.
  • Remoção da Atividade:

    • Usa _context.Atividades.Remove(atividade) para marcar a atividade para remoção do contexto.

Com essas atualizações, nosso CRUD no Controller está pronto para receber todos os métodos HTTP (GET, POST, PUT e DELETE).

Arquivo AtividadeController.cs em Controllers/AtividadesController.cs após implementação do método DELETE:
Bloco de código após implementação do método Delete

Clique aqui para ver no Github.

Agora, vamos executar o projeto e realizar a exclusão de uma atividade específica.

  • Para este exemplo, vamos remover a atividade "Lavar Louça" com o ID 4.
    • No Swagger, localize o método DELETE correspondente.
    • Insira o ID 4 e clique no botão "Executar".

Imagem para deletar o ID 4 via Swagger

Após a execução, a atividade será removida com sucesso. Para confirmar, você pode realizar uma requisição GET. Ao visualizar o resultado, perceberá que a atividade "Lavar Louça" foi removida e não aparece mais na lista de itens pendentes.

Visualização via Swagger do método Delete
Resultado final via Swagger do método Delete

Sinta-se à vontade para explorar mais: crie novos itens, edite os existentes e faça requisições para verificar as informações. Além disso, sugiro que você explore o banco de dados diretamente para acompanhar as alterações em tempo real.

Conclusão & Resumo

Trilhamos um longo caminho. Se você chegou até aqui, você agora é capaz de entender como funciona uma API, alguns conceitos da propedeúticas que lhe ajudará durante os seus estudos.

Vale destacar que este CRUD é uma implementação básica. Em uma aplicação .NET real, você encontrará uma estrutura muito mais complexa, com várias camadas e funcionalidades avançadas. Este artigo foca apenas na estrutura fundamental de uma API para proporcionar uma compreensão inicial.

Neste artigo, exploramos a criação da API DessaVezEuNaoEsqueco, mergulhando nos conceitos fundamentais do .NET 8.0 e do Entity Framework Core. Desde a compreensão do .NET e C#, passando pela definição e funcionamento de uma API até a implementação prática.

Espero que este artigo tenha sido um recurso valioso para você, ajudando a desmistificar o desenvolvimento de APIs e fornecendo uma base sólida para projetos futuros.

. .
Terabox Video Player