Skip to main content

Implementação dos Controllers

Os controladores na arquitetura de uma aplicação são responsáveis por receber as requisições HTTP, delegar a lógica de negócios para os serviços e devolver as respostas ao cliente. Aqui está uma exploração de como os controllers podem ser implementados, utilizando ou não a herança de BaseController.

Controller Básico

Um exemplo simples de um controller que utiliza o BaseController para aproveitar funcionalidades comuns de CRUD:

package com.webpublico.ead.api.controller.academico;

import com.webpublico.ead.api.controller.BaseController;
import com.webpublico.ead.api.dto.academico.TopicoDTO;
import com.webpublico.ead.api.mapper.BaseApiMapper;
import com.webpublico.ead.application.service.academico.TopicoService;
import com.webpublico.ead.domain.model.academico.Topico;
import com.webpublico.ead.util.ApiEndpoint;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(ApiEndpoint.TOPICOS)
@RequiredArgsConstructor
public class TopicoController extends BaseController<Topico, TopicoDTO> {

private final TopicoService service;
private final TopicoApiMapper mapper;

@Override
protected BaseService<Topico> getService() {
return service;
}

@Override
protected BaseApiMapper<Topico, TopicoDTO> getMapper() {
return mapper;
}

}

Controller com Regras Específicas

Para cenários mais complexos, onde são necessárias regras específicas ou manipulação de múltiplos modelos de domínio, o controller pode se afastar do modelo genérico e implementar lógicas customizadas:

package com.webpublico.ead.api.controller.academico;

import com.webpublico.ead.application.service.BaseService;
import com.webpublico.ead.application.service.academico.TopicoService;
import com.webpublico.ead.domain.model.academico.Topico;
import com.webpublico.ead.util.ApiEndpoint;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(ApiEndpoint.TOPICOS)
@RequiredArgsConstructor
public class TopicoController extends BaseController<Topico, TopicoDTO> {

private final TopicoService service;
private final TopicoDisciplinaService topicoDisciplinaService;
private final TopicoApiMapper mapper;
private final TopicoDisciplinaMapper topicoDisciplinamapper;

@GetMapping(ApiEndpoint.TOPICO_DISCIPLINAS)
public List<TopicoDisciplinaDTO> listarDisciplinasDoTopico(@PathVariable String topicoId) {
Set<TopicoDisciplina> topicoDisciplinas = topicoDisciplinaService.buscarDisciplinasPorTopicoId(topicoId);
return topicoDisciplinamapper.toCollectionDTO(topicoDisciplinas);
}

@Override
@PutMapping
public TopicoDTO atualizar(@RequestBody @Valid TopicoDTO topicoDTO) {
Topico topicoExistente = service.buscarTopicoComDisciplinas(topicoDTO.getId());
mapper.updateDomain(topicoDTO, topicoExistente);
Topico topicoAtualizado = service.salvar(topicoExistente);
return mapper.toDTO(topicoAtualizado);
}

@Override
protected BaseService<Topico> getService() {
return service;
}

@Override
protected BaseApiMapper<Topico, TopicoDTO> getMapper() {
return mapper;
}

}

Importância dos Mappers e DTOs

  • Mappers: Independentemente da herança do BaseController, o uso de mappers é essencial para transformar dados entre DTOs e entidades de domínio. Eles facilitam a manutenção do código e ajudam a manter a separação de preocupações entre as camadas da aplicação.

  • DTOs: Os Data Transfer Objects (DTOs) são vitais para a transferência de dados entre a camada de front-end e a de serviço. Eles ajudam a otimizar as requisições e respostas ao incluir apenas os dados necessários para cada operação.

Utilização de ApiEndpoint

A classe ApiEndpoint é utilizada para centralizar as constantes dos endpoints, garantindo a consistência e facilitando a manutenção dos caminhos de acesso definidos na aplicação. A adoção dessa prática contribui para um código mais limpo e organizado.