Pular para o conteúdo
.NETRetornando recursos do banco
Módulo 03Construindo a Web API

Retornando recursos do banco

iniciante 25 min de leitura·Atualizado · .NET 9
Resumo

Ligamos o controller à Service Layer para buscar categorias reais do banco e retorná-las com os status codes HTTP apropriados.

1. Objetivos de Aprendizagem#

  • Injetar a Service Layer no controller.
  • Retornar coleções e recursos únicos com Ok, NotFound.
  • Usar IServiceManager para orquestrar a busca.

2. Pré-requisitos#

  • Controllers e roteamento (tópico 18.1).

3. Conceito#

O controller não acessa o DbContext diretamente: ele chama a Service Layer, que usa o IRepositoryManager. Isso preserva a separação de camadas do Onion. Retornamos IActionResult para escolher o status code correto: 200 OK com corpo, 404 Not Found quando o recurso não existe.

4. Mão na Massa#

4.1. Setup#

Assuma um IServiceManager (análogo ao IRepositoryManager) já registrado como Scoped.

4.2. Implementação Passo a Passo#

  1. Serviço:
C#
public interface ICategoriaService
{
    Task<IEnumerable<Categoria>> GetAllAsync(bool trackChanges);
}

public class CategoriaService : ICategoriaService
{
    private readonly IRepositoryManager _repo;
    public CategoriaService(IRepositoryManager repo) => _repo = repo;

    public async Task<IEnumerable<Categoria>> GetAllAsync(bool trackChanges) =>
        await _repo.Categoria.GetAllAsync(trackChanges);
}
  1. Controller consumindo o serviço:
C#
[HttpGet]
public async Task<IActionResult> GetCategorias()
{
    var categorias = await _service.Categoria.GetAllAsync(trackChanges: false);
    return Ok(categorias);
}

4.3. Executando#

Shell
dotnet run
curl http://localhost:5000/api/categorias

Retorna 200 OK com a lista em JSON.

5. Exemplo Completo#

C#
[ApiController]
[Route("api/categorias")]
public class CategoriasController : ControllerBase
{
    private readonly IServiceManager _service;
    public CategoriasController(IServiceManager service) => _service = service;

    [HttpGet]
    public async Task<IActionResult> GetCategorias()
    {
        var categorias = await _service.Categoria.GetAllAsync(trackChanges: false);
        return Ok(categorias);
    }
}

6. Boas Práticas e Armadilhas#

FaçaEvite
Usar trackChanges: false em leiturasRastrear entidades desnecessariamente
Retornar status codes semânticosRetornar sempre 200, mesmo em erro
Manter o controller fino, delegando ao serviçoLógica de negócio dentro da ação
Atenção

retornar a entidade diretamente vaza o modelo de domínio para o cliente (e pode causar loops de serialização em relacionamentos). No próximo tópico introduzimos DTOs para resolver isso.

7. Segurança e Produção#

  • Expor entidades cruas pode revelar campos internos (ex.: flags, chaves). Sempre projete para DTOs em endpoints públicos.
  • Consultas de leitura devem ser paginadas em coleções grandes (Módulo 30) para evitar respostas gigantes.

8. Exercícios#

  • Fácil: adicione GET /api/produtos retornando todos os produtos.
  • Médio: trate o caso de coleção vazia retornando 200 com lista vazia (não 404).
  • Desafio: meça o tempo de resposta com e sem AsNoTracking em uma tabela grande.

9. Resumo#

O controller delega à Service Layer, que usa o repositório para buscar dados. Retornamos status codes semânticos e identificamos o problema de expor entidades diretamente.

10. Próximos Passos#

Introduzimos DTOs e AutoMapper para desacoplar o contrato da API do modelo de domínio.

11. Referências#

18-02 — Retornando recursos do banco | Curso ASP.NET Core