CRUD e REST em Java
- #Java
Resumo
CRUD é uma sigla que representa as quatro operações básicas usadas para gerenciar dados em um sistema de computador, Create (Criar), Read (Ler), Update (Atualizar) e Delete (Deletar).
Essas operações são essenciais para quase todos os sistemas que lidam com informações, como bancos de dados e aplicativos.
- Create (Criar): Refere-se à ação de adicionar novos dados ao sistema. No contexto de um banco de dados, isso significa inserir um novo registro.
- Read (Ler): É a operação de leitura, onde os dados existentes são consultados e apresentados. Essa operação é utilizada para buscar, listar ou visualizar os dados.
- Update (Atualizar): O update serve para modificar dados já existentes no sistema. Quando algum registro precisa ser alterado ou corrigido, é utilizada essa operação.
- Delete (Deletar): Refere-se à remoção de dados do sistema. Isso significa que um registro será permanentemente excluído do banco de dados.
Além disso, vou abordar o conceito de REST (Representational State Transfer). REST é um estilo arquitetônico para a construção de APIs web, baseado em princípios que facilitam a comunicação entre clientes e servidores. Ele utiliza métodos HTTP padrão (GET, POST, PUT, DELETE) para operações CRUD e promove uma arquitetura sem estado e baseada em recursos.
Exemplo prático
Vou explorar o conceito de CRUD e REST usando um exemplo prático: um sistema de gestão de exercícios de academia que estou desenvolvendo. Esse sistema permite a adição, visualização, atualização e exclusão de registros de exercícios.
Create (Criar)
Objetivo: Adicionar um novo exercício ao sistema.
Descrição: A operação Create é usada para adicionar novos registros de exercícios ao sistema. Vamos analisar o código que implementa essa operação em duas partes: o serviço (ExerciseService) e o controlador (ExerciseCreateController).
Serviço
Objetivo: A parte logica do código para salvar o exercício no banco de dados.
Explicação:
- Criação de Instância: Uma nova instância da entidade Exercise é criada. Essa entidade representa a estrutura de dados no banco de dados.
- Definição de Propriedades: As propriedades do exercício, como nome, descrição, equipamento e grupo muscular, são definidas com base nos dados fornecidos no ExerciseDTO. O DTO (Data Transfer Object) é um objeto que transporta dados entre as camadas do sistema.
- Salvamento: A entidade preenchida é salva no banco de dados usando o repositório (repository.save(exerciseEntity)). O repositório é uma interface que fornece operações básicas de persistência.
- Tratamento de Exceções: Se ocorrer um erro durante o salvamento, uma exceção personalizada (BusinessException) é lançada com uma mensagem explicativa.
Controlador para Criação
Objetivo: Receber solicitações HTTP para criar novos exercícios e encaminhá-las para o serviço.
Explicação:
- Roteamento: O controlador é anotado com @RestController e @RequestMapping("/exercise"), indicando que ele lida com solicitações HTTP no caminho /exercise.
- Método PersistController: Este método é chamado quando uma solicitação POST é feita para o endpoint /exercise. Ele recebe um objeto ExerciseDTO no corpo da solicitação (@RequestBody @Valid ExerciseDTO exerciseDTO).
- Chamada ao Serviço: O método PersistController invoca o serviço (exerciseService.saveExercise(exerciseDTO)) para processar a criação do exercício.
- Resposta HTTP: Se a criação for bem-sucedida, o método retorna uma resposta HTTP 201 (Criado) com uma mensagem de sucesso. Se ocorrer uma exceção de negócios, a exceção é tratada e propagada.
Read (Ler)
Objetivo: Recuperar e exibir informações sobre exercícios existentes no sistema.
Descrição: A operação Read é usada para consultar e recuperar dados sobre exercícios já registrados no banco de dados. Vamos analisar o código que implementa essa operação em duas partes: o serviço (ExerciseService) e o controlador (ExerciseReadController).
Serviço
Objetivo: Implementar a lógica de recuperação de dados sobre exercícios.
Explicação:
- Listagem de Exercícios: O método listExercice recupera todos os registros de exercícios do banco de dados usando repository.findAll(). Cada entidade Exercise é convertida em um ExerciseDTO usando o método toDto, e a lista de DTOs é retornada.
- Busca por ID: O método findById busca um exercício específico pelo seu ID usando repository.findById(id). Se o exercício não for encontrado, uma exceção BusinessException é lançada. Se encontrado, a entidade é convertida para um DTO e retornada.
- Busca por Nome: O método findyByName busca um exercício pelo nome usando repository.findByName(name). Se o exercício não for encontrado, uma exceção BusinessException é lançada. Se encontrado, a entidade é convertida para um DTO e retornada.
- Conversão de Entidade para DTO: O método toDto converte uma entidade Exercise em um ExerciseDTO, definindo todos os atributos do DTO com base nos valores da entidade. O DTO (Data Transfer Object) é utilizado para transferir dados entre as camadas do sistema de forma estruturada e segura.
Controlador para Leitura
Objetivo: Receber solicitações HTTP para recuperar informações sobre exercícios e encaminhá-las para o serviço.
Explicação:
- Roteamento: O controlador é anotado com @RestController e @RequestMapping("/exercise"), indicando que ele lida com solicitações HTTP no caminho /exercise.
- Método ListController: Este método é chamado quando uma solicitação GET é feita para o endpoint /exercise/list. Ele retorna uma lista de todos os exercícios, chamando o método listExercice do serviço.
- Método findById: Este método é chamado quando uma solicitação GET é feita para o endpoint /exercise/id/{id}. Ele retorna um exercício específico baseado no ID fornecido, chamando o método findById do serviço.
- Método findByName: Este método é chamado quando uma solicitação GET é feita para o endpoint /exercise/name/{name}. Ele retorna um exercício específico baseado no nome fornecido, chamando o método findyByName do serviço.
Update (Atualizar)
Objetivo: Modificar um exercício existente, dependendo da presença de um identificador (ID).
Descrição: A operação Update é usada para alterar os detalhes de um exercício existente no sistema. Se o identificador (ID) estiver presente, o exercício existente é atualizado; se não estiver presente, um novo exercício pode ou não ser criado, no caso do meu código, ele cria. Vamos analisar o código que implementa essa operação em duas partes: o serviço (ExerciseServiceImpl) e o controlador (ExerciseCreateAndUpdateController).
Serviço
Objetivo: A parte logica do código para atualizar um exercício no banco de dados.
Explicação:
- Verificação do ID: O método saveOrUpdateExercise verifica se o ID do exerciseDTO é nulo. Se o ID for nulo, isso indica que o exercício é novo e precisa ser criado. Caso contrário, a operação é uma atualização.
- Criação de Nova Entidade: Se o ID estiver ausente, uma nova instância de Exercise é criada, preenchida com os dados do ExerciseDTO, e salva no banco de dados.
- Atualização de Entidade Existente: Se o ID estiver presente, o método tenta encontrar o exercício existente no banco de dados. Se encontrado, a entidade é atualizada com os dados do ExerciseDTO e salva novamente.
- Método entityToDto: Este método é responsável por copiar os dados do ExerciseDTO para a entidade Exercise. Ele garante que os atributos da entidade sejam atualizados conforme os dados recebidos.
Controlador para Atualização
Objetivo: Receber solicitações HTTP para criar ou atualizar exercícios e encaminhá-las para o serviço.
Explicação:
- Roteamento: O controlador é anotado com @RestController e @RequestMapping("/exercise"), indicando que ele lida com solicitações HTTP no caminho /exercise.
- Método PersistController: Este método é chamado quando uma solicitação POST é feita para o endpoint /exercise. Ele recebe um objeto ExerciseDTO no corpo da solicitação (@RequestBody @Valid ExerciseDTO exerciseDTO) e chama o método saveOrUpdateExercise do serviço.
- Resposta HTTP: Após a chamada ao serviço, o método verifica se o ID do ExerciseDTO é nulo. Se for, isso indica que um novo exercício foi criado, e o método retorna uma resposta HTTP 201 (Criado). Se o ID não for nulo, isso indica uma atualização, e o método retorna uma resposta HTTP 202 (Aceito).
Delete (Excluir)
Objetivo: Remover um exercício existente do sistema com base no identificador (ID) ou nome.
Descrição: A operação Delete é usada para excluir registros de exercícios do sistema. Dependendo da entrada, um exercício pode ser excluído pelo seu ID ou pelo seu nome. Vamos analisar o código que implementa essa operação em duas partes: o serviço (ExerciseServiceImpl) e o controlador (ExerciseDeleteController).
Serviço
Objetivo: A parte logica do código para buscar e deletar o exercício no banco de dados.
Explicação:
- Método deleteExerciseById: Este método recebe um ID como parâmetro e tenta remover o exercício correspondente do banco de dados. Se ocorrer algum erro, uma exceção personalizada (BusinessException) é lançada.
- Método deleteExerciseByName: Este método busca o exercício pelo nome. Se o exercício for encontrado, ele é removido usando o ID. Se não for encontrado, uma exceção é lançada. Esse método permite excluir um exercício com base no nome, o que pode ser útil quando o ID não é conhecido.
Controlador para Exclusão
Objetivo: Receber solicitações HTTP para excluir exercícios e encaminhá-las para o serviço.
Explicação:
- Roteamento: O controlador é anotado com @RestController e @RequestMapping("/exercise"), indicando que ele lida com solicitações HTTP no caminho /exercise.
- Método deleteExerciseId: Este método é chamado quando uma solicitação DELETE é feita para o endpoint /exercise/delete/id/{id}. Ele recebe um ID como parâmetro (@PathVariable Long id) e chama o serviço para excluir o exercício correspondente. Em caso de sucesso, uma resposta HTTP 200 (OK) é retornada com uma mensagem de sucesso.
- Método deleteExerciseName: Este método é chamado quando uma solicitação DELETE é feita para o endpoint /exercise/delete/name/{name}. Ele recebe um nome como parâmetro (@PathVariable String name) e chama o serviço para excluir o exercício correspondente. Em caso de sucesso, uma resposta HTTP 200 (OK) é retornada com uma mensagem de sucesso.
Conclusão
Neste artigo, exploramos a implementação das operações básicas de um sistema de gerenciamento de exercícios em uma aplicação Spring Boot, utilizando uma arquitetura baseada em serviços e controladores REST.
Tentei usar partes do código de um programa que estou desenvolvendo sozinho, para poder analisar cada operação CRUD.
O código completo se encontra disponível no meu GitHub: https://github.com/leandroalves2/gym-manager
Sugestões e criticas são sempre bem vindas.