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.