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


Justificativa para o uso dessa arquitetura
Embora as arquiteturas modernas privilegiem regras de negócio na aplicação e sigam princípios como DDD e Clean Architecture, ainda existem cenários legítimos em que Stored Procedures são utilizadas para encapsular lógica diretamente no banco de dados. Isso pode acontecer por motivos como:
Restrições técnicas de sistemas legados;
Demandas específicas de performance;
Políticas internas de segurança ou governança;
Decisões estratégicas da equipe ou da empresa.
Nesta série de artigos sobre a construção de uma API REST com Stored Procedures, o objetivo não é incentivar o uso indiscriminado dessa abordagem, mas sim mostrar como aplicá-la de forma estruturada e organizada quando ela for necessária. Em muitos projetos reais, é preciso adaptar a solução à realidade do ambiente, respeitando restrições e práticas já existentes.
Criando um Novo Projeto no Visual Studio 2022
Para começarmos a construção da nossa API REST com .NET 8, o primeiro passo é criar um novo projeto no Visual Studio 2022. Essa será a IDE utilizada em toda a implementação. Siga os passos abaixo para chegar até a tela de seleção de templates:
Com o Visual Studio 2022 aberto, clique no menu
File > New - Project
;Isso abrirá uma nova janela com o título “Create a new project” ou “Add a new project” (dependendo da sua versão/idioma).
No campo de busca, digite “API” e selecione o template “ASP.NET Core Web API”;
Verifique se a linguagem está definida como C#;
Clique em Next para prosseguir com a configuração do projeto.
Esta etapa define a base de nossa aplicação que será uma API REST desacoplada utilizando Stored Procedures com Oracle XE 21c.
Configurando o Nome do Projeto
Após selecionar o template ASP.NET Core Web API, o Visual Studio exibirá a tela “Configure your new project”. Essa etapa é responsável por definir o nome do seu projeto e o local onde ele será salvo.
Em Project name, insira um nome descritivo. Neste exemplo, utilizamos, OracleCrud.Sp.Api, indicando que o projeto é um CRUD com Oracle utilizando Stored Procedures;
Em Location, escolha a pasta onde o projeto será armazenado. No nosso caso, estamos organizando dentro da estrutura
src/
do repositório.
Após configurar, clique em Next para prosseguir com a escolha da versão do .NET.
Definindo as Configurações Adicionais do Projeto
Na última etapa da criação do projeto, temos a tela “Additional information”, onde configuramos detalhes importantes da nossa ASP.NET Core Web API. Veja abaixo as opções recomendadas para o nosso cenário com .NET 8 e Oracle XE:
Framework: Selecione o
.NET 8 (Long Term Support)
, que oferece suporte de longo prazo e é ideal para novos projetos.Authentication type: Marque como
None
, já que neste exemplo não implementamos autenticação.Configure for HTTPS: Mantenha marcado para garantir a segurança nas requisições.
Enable OpenAPI support: Marque essa opção para que o Swagger seja configurado automaticamente, facilitando testes na API.
Use controllers: Certifique-se de que está marcado, pois usaremos controllers no estilo tradicional (e não minimal APIs).
Por fim, clique em Create para gerar sua API REST. Pronto! Agora temos a estrutura inicial do nosso projeto ASP.NET Core com suporte a Swagger e pronto para integrar com Oracle via Stored Procedures.
Limpando a Estrutura Inicial do Projeto
Após a criação da PAI, o Visual Studio gera alguns arquivos de exemplo que não serão utilizados no projeto. Para manter a organização e focar apenas no que é essencial, recomendamos excluir os seguites arquivos:
Arquivos a serem removidos:
OracleCrud.Sp.Api.http
: Usado para testes HTTP via Visual Studio, mas será desnecessário no nosso fluxo.Controllers/WeatherForecastController.cs
: Um controller gerado automaticamente com lógica fictícia.WeatherForecast.cs
: Classe modelo de exemplo que não utilizaremos.
Para excluir, no Solution Explorer, clique com o botão direito do mouse em cada arquivo, selecione a opção Delete e confirme a exclusão se solicitado.
Separando responsabilidades com DTOs distintos
Para manter a clareza e a responsabilidade única de cada classe em nossa API, utilizamos dois Data Transfer Objects (DTOs) distintos: O CreateUserDto
e o UserDto
. O CreateUserDto
é usado exclusivamente para representar os dados recebidos do frontend no momento da criação de um novo usuário. Ele não inclui o Id, pois esse campo é gerado internamente pela API ou pelo banco de dados. Já o UserDto
, representa o objeto completo, incluindo o Id
, e é utilizado nas respostas ou em operações internas onde o identificador já está presente. Essa separação melhora a coesão do código e facilita a manutenção e os testes da aplicação.
// DTO recebido do Frontend (para criação de usuário)
namespace OracleCrud.Sp.Api.Domain.Dtos;
public class CreateUserDto
{
public string Name { get; set; } = default!;
public string Email { get; set; } = default!;
}
// DTO utilizado internamente (com Id)
namespace OracleCrud.Sp.Api.Domain.Dtos;
public class UserDto
{
public string Id { get; set; } = default!;
public string Name { get; set; } = default!;
public string Email { get; set; } = default!;
}
Por que os DTOs estão na pasta Domain?
Colocamos os DTOs na pasta Domain porque, nesse projeto, não estamos utilizando entidades de domínio mapeadas com ORM como o Entity Framework. Em vez disso, nossos objetos centrais de comunicação com a API(como UserDto
e CreateUserDto
) representam o “contrato” de dados que a aplicação conhece e manipula, sendo parte da camada de domínio. Isso reforça a ideia de que o domínio não é só composto por entidades persistidas, mas também pelos tipos que expressam regras e estruturas de negócio, mesmo que simplificadas.
Definindo Contratos com Interfaces: Separando Regras de Negócio e Persistência
Na estrutura desta API, criamos duas interfaces fundamentais para garantir a separação de responsabilidade IUserService
e IUserRepository
. A IUserService
representa o contrato da camada de serviço, responsável por orquestrar as regras de negócio da aplicação. Já a IUserRepository
define o contrato da camada de persistência de dados, isolando a forma como acessamos o Oracle Database através de stored procedures.
using OracleCrud.Sp.Api.Domain.Dtos;
namespace OracleCrud.Sp.Api.Application.Interfaces;
public interface IUserService
{
Task<IEnumerable<UserDto>> GetAllAsync();
Task<string> InsertAsync(CreateUserDto user);
Task<string> UpdateAsync(UserDto user);
Task<string> DeleteAsync(string id);
}
Ambas as interfaces foram posicionadas na pasta Application/Interfaces
, pois essa camada representa a lógica da aplicação (application layer), isto é , o ponto de comunicação entre as regras de negócio e as implementações concretas.
using OracleCrud.Sp.Api.Domain.Dtos;
namespace OracleCrud.Sp.Api.Application.Interfaces;
public interface IUserRepository
{
Task<IEnumerable<UserDto>> GetAllAsync();
Task<string> InsertAsync(UserDto user);
Task<string> UpdateAsync(UserDto user);
Task<string> DeleteAsync(string id);
}
Manter as interfaces nesse local centraliza os contratos da aplicação, facilitando a leitura, os testes e futuras substituições de implementação (por exemplo, trocar Oracle por outro banco, sem impactar as camadas superiores). Essa decisão segue os princípios da arquitetura limpa promovendo uma baixo acoplamento e e facilitando a manutenção da solução.
Conclusão
Nesta Parte 1 da série Construindo a API REST em .NET com Oracle XE e Stored Procedures, iniciamos o desenvolvimento da aplicação partindo totalmente do zero. Realizamos a seguintes etapas:
Criamos o projeto com o template ASP.NET Core Web API no Visual Studio 2022;
Limpamos a estrutura inicial removendo arquivos de exemplo como
WeatherForecast.cs
eWeatherForecastController.cs
;Organizamos a base do projeto como uma estrutura em camadas:
Domain
,Application
,Infrastructure
eControllers
;Definimos os DTOs
CreateUserDto
eUserDto
, explicando seus papéis e porque estão posicionados dentro da camada de domínio;Criamos as interfaces
IUserService
eIUserRepository
, que representam os contratos da camada de aplicação.Justificamos a separação das interfaces em Application/Interfaces, mantendo o foco em uma arquitetura limpa e desacoplada.
Na Parte 2, vamos dar continuidade à implementação, criando os repositórios concretos, integrando com o banco Oracle XE por meio de Stored Procedures e finalizando os endpoints da nossa API REST.
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
