ASP.NET Web API e Azure (.NET)¶
Definição: ASP.NET Web API
ASP.NET Web API é o framework da plataforma .NET para criar serviços HTTP/REST. Na versão do livro-base (Web API 2, 2014, .NET Framework + IIS), as APIs eram uma peça separada; hoje o equivalente é o ASP.NET Core Web API (multiplataforma, open source), que mantém os mesmos conceitos: controladores, ações, rotas, serialização JSON e injeção de dependência.
Esta página reúne os conceitos reutilizáveis; os passos de tela do Visual Studio e do portal Azure da época estão obsoletos e foram omitidos. Para os princípios de REST, veja Backend; para a alternativa em Java, Spring.
Controladores, ações e rotas¶
- Controller é a classe que trata requisições HTTP; seus métodos públicos são as actions. O framework mapeia o verbo HTTP e a URL para a
ação (
GET /api/produtos/5→Get(5)). - Roteamento por convenção (padrão
api/{controller}/{id}) ou por atributos ([Route("api/produtos/{id}")],[HttpGet]), que dá controle total e é o padrão atual. - Tipos de retorno: o tipo do domínio (o framework serializa em JSON/XML por content negotiation) ou um resultado HTTP que controla status e cabeçalhos:
Ok(obj)(200),Created(...)/CreatedAtAction(201),NoContent()(204),BadRequest()(400),NotFound()(404),StatusCode(500). - Documentação: hoje por OpenAPI/Swagger (antes, páginas de ajuda e WADL), que também alimenta clientes gerados e testes com Postman.
[ApiController]
[Route("api/produtos")]
public class ProdutosController : ControllerBase
{
private readonly LojaContext _db;
public ProdutosController(LojaContext db) => _db = db; // injeção de dependência
[HttpGet]
public async Task<IEnumerable<Produto>> Listar() => await _db.Produtos.ToListAsync();
[HttpGet("{id:int}")]
public async Task<ActionResult<Produto>> Obter(int id)
{
var p = await _db.Produtos.FindAsync(id);
return p is null ? NotFound() : Ok(p);
}
[HttpPost]
public async Task<ActionResult<Produto>> Criar(Produto p) // [ApiController] já valida o modelo e devolve 400
{
_db.Produtos.Add(p);
await _db.SaveChangesAsync();
return CreatedAtAction(nameof(Obter), new { id = p.Id }, p);
}
}
Persistência com Entity Framework¶
- Entity Framework (EF) é o ORM da plataforma .NET (hoje EF Core). Abordagem Code First: você escreve as classes do modelo e o EF cria e evolui o banco por migrações.
- Um
DbContextrepresenta a sessão com o banco e expõeDbSet<T>por tabela (equivalente aoEntityManager/repositórios do JPA, veja Acesso a dados). - Migrações:
Add-Migration/dotnet ef migrations addgera o código da mudança;Update-Database/dotnet ef database updateo aplica; o EF guarda o histórico em uma tabela (__EFMigrationsHistory) e executa só o que falta. Um método de seed popula dados iniciais. - LINQ e lambdas: consultas fortemente tipadas em C# que viram SQL (
_db.Produtos.Where(p => p.Preco > 10).OrderBy(p => p.Nome)); evite trazer tudo para a memória antes de filtrar.
Validação do modelo¶
Atributos de Data Annotations nas propriedades: [Key] (chave primária), [Required] (obrigatório, com mensagem), [MaxLength]/[StringLength], [Range],
[RegularExpression]. Com [ApiController] (ou checando ModelState.IsValid), requisições inválidas voltam 400 Bad Request com os erros por campo. Para regras mais ricas,
FluentValidation (em Java, o equivalente é o Bean Validation, veja Spring).
Autenticação e autorização¶
- Autenticação responde "quem é você?"; autorização, "o que pode fazer?". No livro, o OAuth 2.0 com Resource Owner Password e tokens do tipo bearer
em um servidor de autorização embutido, com usuários e papéis (
ADMIN,USER) em tabelas do ASP.NET Identity (AspNetUsers,AspNetRoles). [Authorize]protege um controlador ou ação ([Authorize(Roles = "ADMIN")]); sem a anotação, nada é exigido mesmo com o mecanismo configurado (erro comum).[AllowAnonymous]abre exceções.- Hoje: JWT bearer com ASP.NET Core Identity ou provedores externos (Microsoft Entra ID/Azure AD, Keycloak), com fluxo authorization code + PKCE para clientes públicos (o grant password é desencorajado) (OAuth e JWT).
Roteamento avançado e integração¶
- Novas operações em um serviço: rotas por atributo, parâmetros de rota/consulta/corpo (
[FromBody],[FromQuery]), verbos próprios (/api/pedidos/{id}/cancelar). - Integração: consumir serviços SOAP (cliente gerado a partir do WSDL; exemplo clássico: cálculo de frete dos Correios) e REST (
HttpClient, comIHttpClientFactory) de dentro de uma ação, útil em integração de sistemas (SOAP e REST). Use timeouts, retries e circuit breaker (Polly) (resiliência).
Publicando no Azure¶
- Azure App Service hospeda a API (PaaS); o Azure SQL Database guarda os dados; o perfil de publicação ou, hoje, GitHub Actions/Azure DevOps fazem o deploy (CI/CD). As migrações podem rodar na publicação (opção Code First Migrations).
- Monitoração e diagnóstico: log streaming, tracing da aplicação e métricas no portal; hoje Application Insights e OpenTelemetry (Observability). Configuração e segredos em App Settings e Key Vault, não no código.
- Conceitos de PaaS, banco gerenciado e regiões em Nuvem.
.NET e C#: fundamentos da plataforma¶
Definição: .NET
.NET é a plataforma da Microsoft para criar aplicações (web, desktop, mobile, nuvem, jogos). Ela reúne linguagens (C#, F#, VB.NET), uma máquina virtual (o CLR, Common Language Runtime) e uma biblioteca de classes (BCL). A versão do livro-base (.NET Framework 3.5/4, 2008 a 2010, só Windows) evoluiu para o .NET moderno (.NET 6, 8, 9...), multiplataforma e de código aberto.
Como o código C# é executado¶
flowchart LR
A["Código C#<br/>(.cs)"] -->|compilador| B["CIL / MSIL<br/>(assembly .dll/.exe)"]
B -->|CLR + JIT| C["Código nativo<br/>da máquina"]
- O compilador gera CIL (Common Intermediate Language), um código intermediário parecido com o bytecode do Java (JVM); o JIT o traduz para código nativo na execução. Há também AOT (compilação antecipada).
- CTS (Common Type System) define os tipos comuns entre linguagens .NET, o que permite que um componente em C# seja usado em F# ou VB.NET. O coletor de lixo (GC) libera a memória automaticamente.
- Um assembly é a unidade de distribuição e versionamento (
.dllou.exe); um namespace agrupa tipos e evita conflitos de nome; ousingo importa.
Tipos: valor x referência¶
| Aspecto | Tipo de valor (struct, int, bool, enum) |
Tipo de referência (class, string, arrays, interface) |
|---|---|---|
| Armazenamento | Normalmente na pilha (stack) ou embutido no objeto | Objeto no heap; a variável guarda a referência |
| Atribuição | Copia o valor | Copia a referência (dois nomes para o mesmo objeto) |
| Nulo | Não aceita null, a menos que seja int? (nullable) |
Aceita null (veja nullable reference types) |
Boxing é converter um valor em object (aloca no heap) e unboxing é o caminho inverso; ambos têm custo.
Strings são imutáveis: concatenar muito em loop cria muitos objetos, então use StringBuilder.
A linguagem C# em um exemplo¶
public interface IDesconto { decimal Calcular(decimal valor); }
public class DescontoFixo : IDesconto
{
private readonly decimal _percentual; // campo privado, imutável após o construtor
public DescontoFixo(decimal percentual) => _percentual = percentual;
public decimal Calcular(decimal valor) => valor * _percentual / 100;
}
public class Pedido
{
public int Id { get; init; } // propriedade auto-implementada (get/set sem código extra)
public List<decimal> Itens { get; } = new();
public decimal Total => Itens.Sum(); // propriedade calculada (expression-bodied)
public decimal TotalCom(IDesconto desconto) => Total - desconto.Calcular(Total);
}
var pedido = new Pedido { Id = 1 };
pedido.Itens.AddRange(new[] { 50m, 70m });
Console.WriteLine($"Total: {pedido.TotalCom(new DescontoFixo(10)):C}"); // interpolação e formato de moeda
- Propriedades (
get/set/init) substituem os getters e setters manuais do Java;recordcria tipos imutáveis com igualdade por valor (equivalente aorecorddo Java moderno). - Orientação a objetos: classes, herança (
: ClasseBase),virtual/override,abstract, interfaces e modificadorespublic,private,protected,internal(visível no assembly). Veja a teoria em Orientação a Objetos. - Tratamento de erros:
try/catch/finallyethrow;usinggarante a liberação de recursos que implementamIDisposable(como otry-with-resourcesdo Java). Prefira capturar exceções específicas. - Genéricos e coleções:
List<T>,Dictionary<K,V>,HashSet<T>;varinfere o tipo local. - Delegates, lambdas e eventos: delegate é um tipo que representa uma função (
Func<>,Action<>); lambdas (x => x * 2) e eventos (padrão observer, ver Padrões) se apoiam nele. - LINQ consulta qualquer coleção (ou banco, via Entity Framework) com sintaxe parecida com SQL:
itens.Where(i => i > 50).OrderBy(i => i).Select(i => i * 2). async/awaitescreve código assíncrono de forma sequencial, sobreTask: libera a thread durante esperas de I/O e é a base de qualquer API ASP.NET Core moderna.
Acesso a dados: do ADO.NET ao Entity Framework¶
ADO.NET é a camada base de acesso a bancos no .NET, equivalente ao JDBC do Java (Acesso a dados):
| Objeto ADO.NET | Papel | Equivalente em JDBC |
|---|---|---|
SqlConnection |
Abre a conexão (string de conexão) | Connection |
SqlCommand |
Executa SQL ou procedimento; aceita parâmetros | PreparedStatement |
SqlDataReader |
Lê o resultado linha a linha, só para frente, conectado | ResultSet |
DataSet/DataAdapter |
Cópia desconectada dos dados em memória | (não há equivalente direto) |
using var conexao = new SqlConnection(stringDeConexao);
await conexao.OpenAsync();
using var cmd = new SqlCommand("SELECT Nome FROM Cliente WHERE Id = @id", conexao);
cmd.Parameters.AddWithValue("@id", 42); // parâmetros evitam SQL Injection
using var leitor = await cmd.ExecuteReaderAsync();
while (await leitor.ReadAsync()) Console.WriteLine(leitor.GetString(0));
Hoje o caminho usual é o Entity Framework (ORM, seção "Persistência com Entity Framework"), ou o Dapper (micro-ORM leve) quando se quer controlar o SQL.
Aplicações desktop e web no .NET: o que é legado¶
| Tecnologia da época | Situação | Substituto atual |
|---|---|---|
| Windows Forms / WPF | Ainda usadas em desktop Windows | WPF, WinUI, MAUI (multiplataforma) |
ASP.NET Web Forms (eventos e ViewState, páginas .aspx) |
Legado; só manutenção | ASP.NET Core MVC, Razor Pages, Blazor |
| VB.NET | Mantida, sem novos recursos de linguagem | C# |
| .NET Framework (só Windows) | Só correções de segurança | .NET moderno (multiplataforma) |
Para responder em entrevista¶
| Pergunta | Ideias para a resposta |
|---|---|
| "O que é uma action e como o roteamento funciona?" | Método público do controller; mapeado por verbo HTTP + rota (convenção ou atributos) |
| "Code First e migrações?" | Modelo em classes gera/evolui o banco; migrações versionam o esquema e aplicam só o pendente |
| "Como proteger uma API?" | [Authorize] com JWT/OAuth2, papéis ou políticas; HTTPS; validação de entrada; segredos no Key Vault |
| "Diferença entre Web API e ASP.NET Core?" | Web API 2 (.NET Framework, IIS) é o antecessor; Core é multiplataforma, modular, com DI embutida e Kestrel |
| "Como evitar N+1/consultas pesadas com EF?" | Projeções, Include, filtrar no banco, paginação |