Construindo uma API REST em .NET com Oracle XE e Stored Procedures [Parte 3].


Nesta terceira parte, daremos continuidade a construção da nossa API REST em .NET Core com Oracle XE e Stored Procedures.
Camada Controller: o ponto de entrada da API
A camada Controller em uma aplicação ASP.NET Core representa o ponto de entrada das requisições HTTP. Ela é responsável por receber, interpretar e encaminhar as chamadas realizadas pelo cliente, como navegadores, aplicativos móveis ou ferramentas de integração, para o serviços apropriados da aplicação. Os controllers devem ser simples e diretos, delegando toda a lógica de negócio a camada de serviços (Application). Essa separação de responsabilidades mantém o código limpo, testável e aderente aos princípios da arquitetura em camadas. Além disso, cada método do controller é geralmente associado a uma rota e um verbo HTTP(GET, POST, PUT, DELETE), formando os chamados endpoints RESTful.
Implementando a UserController: expondo os endpoints da API
A classe UserController
é responsável por expor os endpoints HTTP da nossa API REST, funcionando como o ponto de entrada das operações relacionadas a usuários. Cada método corresponde a uma ação do CRUD, utilizando os verbos HTTP apropriados (GET
, POST
, PUT
, DELETE
) e delegando as operações à camada de serviço (IUserService
). Essa estrutura mantém o controller enxuto e focado apenas em receber requisições, validar a estrutura dos dados e retornar respostas HTTP padronizadas. A lógica de negócio permanece encapsulada no serviço, garantindo separação de responsabilidade e alinhamento com os princípios da arquitetura em camadas.
using Microsoft.AspNetCore.Mvc;
using OracleCrud.Sp.Api.Application.Interfaces;
using OracleCrud.Sp.Api.Domain.Dtos;
namespace OracleCrud.Sp.Api.Controllers;
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly IUserService _userService;
public UserController(IUserService userService)
{
_userService = userService;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<UserDto>>> GetAll()
{
var users = await _userService.GetAllAsync();
return Ok(users);
}
[HttpPost]
public async Task<ActionResult<string>> Insert([FromBody] CreateUserDto user)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _userService.InsertAsync(user);
return Ok(result);
}
[HttpPut]
public async Task<ActionResult<string>> Update([FromBody] UserDto user)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var result = await _userService.UpdateAsync(user);
return Ok(result);
}
[HttpDelete("{id}")]
public async Task<ActionResult<string>> Delete(string id)
{
var result = await _userService.DeleteAsync(id);
return Ok(result);
}
}
Program.cs: configurando o pipeline e a injeção de dependências
O arquivo Program.cs
é o ponto de entrada da aplicação ASP.NET Core. Nele configuramos o pipeline de execução da aplicação, os serviços que serão injetados via dependência e os middlewares que vão atuar nas requisições HTTP. É nesse local que registramos o IUserService
e o IUserRepository
para que o ASP.NET Core saiba como instanciar essas dependências sempre que forem solicitadas, por exemplo, dentro da UserController
. Também configuramos o Swagger, que facilita o teste manual da API, e definimos o ambiente da aplicação. Essa organização centralizada torna o ciclo de vida da aplicação mais transparente e controlado, seguindo boas práticas modernas de desenvolvimento com .NET.
Injeção de Dependência: conectando interfaces e implementações
No Program.cs, realizamos o registro das interfaces IUserService
e IUserRepository
com suas respectivas implementações UserService
e UserRepository
utilizando o método AddScoped
. Essa abordagem segue o padrão de injeção de dependência nativo do ASP.NET Core, permitindo que o framework forneça automaticamente as instâncias, como nos controllers. O uso do Scoped
garante que uma nova instância será criada por requisição HTTP, o que é ideal para serviços que acessam o banco de dados. Essa prática promove desacoplamento, facilidade de testes e clareza na manutenção, sendo um dos pilares da arquitetura limpa adotada no projeto.
builder.Services.AddControllers();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
Testando o endpoint GET /api/User no Postman
Ao executar o projeto em ambiente de desenvolvimento, o ASP.NET Core gera automaticamente uma URL com porta dinâmica, neste caso http://localhost:5219
, conforme definido no launchSettings.json
. É importante destacar que, no seu ambiente, essa porta pode ser diferente, como 5000
, ou 7048
, dependendo da configuração ou do que o Visual Studio ou SDK do .NET escolherem no momento da execução. Utilizando o Postman, realizamos uma requisição GET
para o endpoint /api/User
, que é responsável por listar todos os usuários cadastrados. A resposta retornou com status 200 OK, indicando que o endpoint está ativo e funcional. No entanto, o corpo da resposta foi um array vazio ([]
), o que significa que nenhum usuário está presente no banco de dados no momento, o que é um comportamento esperado em em um ambiente recém iniciado, antes de qualquer inserção
Testando o endpoint POST /api/User no Postman
Neste teste, utilizamos o Postman para enviar uma requisição POST
ao endpoint /api/User
, com o objetivo de cadastrar um novo usuário. A requisição foi feita com o corpo no formato JSON
, contendo os campos name
e email
, conforme esperado pelo DTO CreateUserDto
. O endpoint respondeu com status 200 OK
e a mensagem “Usuário inserido com sucesso.”, indicando que a operação foi executada corretamente e os dados foram persistidos no banco de dados via stored procedure. Assim como no exemplo anterior, a URL utilizada foi http://localhost:5219
, porém é importante lembrar que essa porta pode variar de acordo com o ambiente de execução de cada desenvolvedor, conforme definido no launchSettings.json
. Se no seu projeto a porta for diferente, isso é completamente normal e não afeta o funcionamento da API.
Reexecutando o GET /api/User para consultar o novo registro
Após a inserção bem sucedida de um novo usuário com o endpoint POST /api/User
, realizamos novamente a requisição GET /api/User para verificar se o dado foi persistido corretamente no banco. Desta vez, o retorno trouxe uma lista contendo o objeto recém cadastrado, incluindo seu id
gerado automaticamente, além dos campos name
e email
. O status 200 OK
confirma que a requisição foi processada com sucesso e que o fluxo de inserção e leitura está funcionando conforme esperado. Esse tipo de verificação é essencial para garantir a integridade dos dados e validar que o repositório está acessando corretamente a base Oracle via stored procedures.
Testando o endpoint PUT /api/User para atualizar um usuário
Neste teste, utilizamos o Postman para enviar uma requisição PUT
ao endpoint /api/User
, com o objetivo de atualizar os dados de um usuário já existente. No corpo da requisição, foi informado o id
do usuário previamente inserido, juntamente com os novos valores para os campos name
e email
. A resposta retornou com status 200 OK
e a mensagem "Usuário atualizado com sucesso.", confirmando que a operação foi concluída com êxito. Isso demonstra que a comunicação com a stored procedure sp_update_user
está funcionando corretamente e que a aplicação está atualizando registros no banco de dados conforme esperado. Lembre-se de que, se o id informado não existir, a própria procedure retorna uma mensagem apropriada, garantindo um controle confiável de validação no nível de banco.
Verificando a atualização com uma nova chamada GET
Após a requisição de atualização com sucesso, reexecutamos o endpoint GET /api/User para verificar se os dados do usuário foram realmente modificados no banco. A resposta confirmou a alteração, retornando o nome atualizado com “Flavio Update” e o nomes e-mail previamente cadastrado. Isso demonstra que o processo de persistência com stored procedure está funcionando corretamente, refletindo imediatamente as mudanças realizadas.
Testando o endpoint DELETE /api/User para remover um usuário
Neste teste, utilizamos o Postman para enviar uma requisição DELETE
ao endpoint /api/User/{id}
, informando diretamente na URL o id do usuário que havia sido previamente inserido e atualizado. A resposta retornou com status 200 OK
e a mensagem "Usuário excluído com sucesso.", confirmando que a operação foi concluída corretamente. Essa resposta é gerada pela stored procedure sp_delete_user
, que também valida se o id
existe no banco e retorna mensagens específicas em caso de erro. Com isso, completamos o ciclo do CRUD (Create, Read, Update, Delete), validando que todas as operações estão integradas corretamente com o banco Oracle.
Conclusão
Na terceira parte da série Construindo uma API REST em .NET com Oracle XE e Stored Procedures [Parte 3], implementamos a camada de controllers da aplicação e realizamos testes práticos dos principais endpoints do CRUD
: GET
, POST
, PUT
e DELETE
. Exploramos como os controllers se comunicam com a camada de serviços, como configurar corretamente a injeção de dependência no Program.cs e validamos toda a integração com o banco de dados Oracle por meio de chamadas HTTP usando o Postman. Com isso, nossa API já é capaz de executar todas as operações básicas com segurança e organização. Na Parte 4, concluiremos a aplicação com um resumo geral do que construímos até aqui, consolidando o aprendizado e reforçando os principais conceitos abordados ao longo da série.
Subscribe to my newsletter
Read articles from Flavio dos Santos directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
