REGISTRO DOI:10.5281/zenodo.10278398
Wellton Manopelli [1]
Felipe Diniz Dallilo [2]
Fabiana Florian[3]
RESUMO
Este trabalho aborda a eficiência na gestão de peças de reposição em concessionárias automotivas, com foco no comércio de peças obsoletas. Inspirado pelo conceito de Kaizen, desenvolvemos uma solução inovadora, utilizando a concessionária Toyota em Araraquara-SP como estudo de caso. O desafio da gestão de estoque de peças obsoletas e a prática de compra entre concessionárias motivaram a criação de uma API REST.
Essa ferramenta estratégica busca facilitar a comunicação entre concessionárias, otimizando transações e reduzindo perdas financeiras. A escolha de tecnologias como Java, Spring Boot e PostgreSQL visa oferecer uma plataforma flexível e escalonável. O desenvolvimento da API não apenas soluciona desafios operacionais atuais, mas também estabelece uma infraestrutura adaptável para evolução futura, destacando-se pela eficiência e potencial de crescimento. Resultados obtidos incluem uma aplicação altamente eficaz, com destaque para o mecanismo de segurança baseado em tokens e a flexibilidade oferecida pela natureza REST da API.
A aplicação demonstrou-se eficiente na manipulação de estoques de peças e na otimização do comércio de peças obsoletas. O mecanismo de segurança baseado em tokens mostrou-se robusto, permitindo camadas distintas de autorização para usuários. Sendo uma API REST, proporciona escalabilidade e a capacidade de implementar novas funcionalidades. Como sugestão para futuras atualizações, considera-se a implementação de um serviço de mensageria para facilitar a interação entre usuários, adicionando uma camada adicional de funcionalidade à aplicação.
Palavras-chave: API, REST, JAVA, KAIZEN, CONCESSIONARIA, ESTOQUE.
ABSTRACT
This work addresses the efficiency in spare parts management in automotive dealerships, with a focus on obsolete parts trading. Inspired by the Kaizen concept, we developed an innovative solution, using the Toyota dealership in Araraquara-SP as a case study. The challenge of managing obsolete parts inventory and the practice of inter-dealership procurement motivated the creation of a REST API. This strategic tool aims to facilitate communication between dealerships, optimizing transactions and reducing financial losses.
The choice of technologies such as Java, Spring Boot, and PostgreSQL aims to provide a flexible and scalable platform. The API’s development not only solves current operational challenges but also establishes an adaptable infrastructure for future evolution, standing out for its efficiency and growth potential. Results obtained include a highly effective application, with emphasis on the token-based security mechanism and the flexibility offered by the REST nature of the API.
The application proved to be efficient in handling parts inventories and optimizing obsolete parts trading. The token-based security mechanism proved to be robust, allowing distinct layers of authorization for users. Being a REST API, it provides scalability and the ability to implement new features. As a suggestion for future updates, the implementation of a messaging service is considered to facilitate user interaction, adding an additional layer of functionality to the application.
Keywords: API, REST, JAVA, KAIZEN, DEALER, INVENTORY.
RESUMEN
Este trabajo aborda la eficiencia en la gestión de repuestos en concesionarios de automóviles, con un enfoque en el comercio de piezas obsoletas. Inspirados en el concepto de Kaizen, desarrollamos una solución innovadora, utilizando el concesionario de Toyota en Araraquara-SP como caso de estudio. El desafío de gestionar el inventario de piezas obsoletas y la práctica de compras entre concesionarios motivaron la creación de una API REST.
Esta herramienta estratégica busca facilitar la comunicación entre concesionarios, optimizando transacciones y reduciendo pérdidas financieras. La elección de tecnologías como Java, Spring Boot y PostgreSQL tiene como objetivo proporcionar una plataforma flexible y escalable. El desarrollo de la API no solo resuelve desafíos operativos actuales, sino que también establece una infraestructura adaptable para la evolución futura, destacándose por su eficiencia y potencial de crecimiento. Los resultados obtenidos incluyen una aplicación altamente efectiva, con énfasis en el mecanismo de seguridad basado en tokens y la flexibilidad ofrecida por la naturaleza REST de la API.
La aplicación demostró ser eficiente en la gestión de inventarios de piezas y en la optimización del comercio de piezas obsoletas. El mecanismo de seguridad basado en tokens resultó ser robusto, permitiendo capas distintas de autorización para los usuarios. Al ser una API REST, proporciona escalabilidad y la capacidad de implementar nuevas funciones. Como sugerencia para futuras actualizaciones, se considera la implementación de un servicio de mensajería para facilitar la interacción entre los usuarios, agregando una capa adicional de funcionalidad a la aplicación.
Palabras clave: API, REST, JAVA, KAIZEN, DISTRIBUIDOR, INVENTARIO.
1 INTRODUÇÃO
A eficiência na gestão de peças de reposição é crucial para o desempenho sustentável das concessionárias. A constante busca por melhoria contínua, alinhada ao conceito japonês de Kaizen, inspirou este trabalho que visou desenvolver uma solução para otimizar o comércio de peças obsoletas entre concessionárias automotivas. Como ponto focal, utilizamos a concessionária Toyota em Araraquara-SP, uma referência no setor, como estudo de caso.
A gestão do estoque de peças, especialmente aquelas consideradas obsoletas, traz consigo um desafio significativo para as concessionárias. O aumento do estoque dessas peças, faz com que a concessionaria muitas vezes sem opções viáveis de venda faça o descarte, resultando em prejuízos substanciais. Atualmente, a prática de compra entre concessionárias da região para lidar com peças obsoletas tornou-se uma alternativa. No entanto, essa abordagem enfrenta obstáculos devido à falta de comunicação efetiva entre as concessionárias, resultando em dificuldades para identificar quais peças estão disponíveis para compra. Diante desse cenário, surge a necessidade premente de uma plataforma que facilite a reunião de concessionárias que precisam vender determinadas peças com aquelas interessadas em comprá-las.
Para a resolução desse problema, desenvolvemos uma API REST que atuará como uma ferramenta estratégica para aprimorar as transações entre concessionárias, otimizando a utilização de peças obsoletas e minimizando perdas financeiras.
Ao integrar tecnologias robustas como Java, Spring Boot e PostgreSQL, buscávamos não apenas solucionar desafios operacionais, mas também criar uma plataforma flexível, escalonável e independente para a comunicação entre concessionárias.
Michele Brito descreve alguns dos benefícios em se desenvolver utilizando a linguagem Java:
“O Java é uma das principais e mais utilizadas linguagens de programação, sendo bem robusta, constantemente atualizada e com uma alta demanda, principalmente quando utilizada com frameworks e plataformas bem completas que trazem de forma mais simples e padronizada projetos capazes de impulsionar o desenvolvimento Java de forma bem mais produtiva, como é o caso do ecossistema Spring.” Michele Brito (2023.p6).
A escolha do Spring Boot foi motivada pela sua agilidade no desenvolvimento e configuração, proporcionando uma implementação mais eficiente e rápida. Com o desenvolvimento desta API REST, nosso objetivo ia além de solucionar o problema atual, visávamos estabelecer uma infraestrutura que se destacasse pela sua adaptabilidade e potencial para evolução futura.
2 REVISÃO BIBLIOGRÁFICA
Este capítulo oferece uma base conceitual essencial para a compreensão e contextualização do desenvolvimento da API REST voltada para otimização do comércio de peças obsoletas entre concessionárias automotivas.
2.1 PostgreSQL: Sistema de Gerenciamento de Banco de Dados (SGBD)
O PostgreSQL, também conhecido como “postgres”, é um SGBD objeto-relacional de código aberto com mais de 30 anos de desenvolvimento ativo. Este sistema robusto e confiável desempenha um papel crucial na persistência de dados, fornecendo um ambiente eficiente e escalável para armazenamento e recuperação de informações.
Ele organiza e cuida das informações, garantindo que estejam prontas para serem encontradas quando necessário. Ele simplifica a tarefa de salvar novos dados e facilita a busca rápida e eficiente quando é hora de acessar informações específicas.
2.2 Spring Boot: Framework para Desenvolvimento Java
O Spring Boot, uma extensão do projeto Spring, destaca-se como um framework Java de código aberto que simplifica consideravelmente o desenvolvimento de aplicações. Sua abordagem é fundamentada na ideia de “convenção sobre configuração”, o que significa que muitas decisões são tomadas por padrão, reduzindo a necessidade de configurações extensivas. Essa característica proporciona agilidade ao processo de desenvolvimento, permitindo a criação rápida e eficiente de aplicativos.
Uma das principais vantagens do Spring Boot é sua integração com o ecossistema Spring mais amplo. Herdando as melhores práticas e soluções consolidadas do Spring Framework, o Spring Boot fornece uma base sólida e confiável para o desenvolvimento de aplicações Java. Sua arquitetura embutida elimina a necessidade de servidores de aplicativos externos, incorporando servidores como Tomcat, Jetty ou Undertow diretamente na aplicação. Além disso, adota um modelo de autoconfiguração inteligente, adaptando-se automaticamente ao ambiente de execução.
No contexto específico deste projeto, o Spring Boot oferece benefícios significativos. Sua popularidade no desenvolvimento de microsserviços e APIs RESTful o torna uma escolha robusta para a criação da nossa API destinada ao comércio de peças obsoletas entre concessionárias automotivas. A facilidade de integração com bancos de dados, com suporte nativo para diversos provedores, incluindo o Hibernate para mapeamento objeto-relacional, simplifica a implementação das funcionalidades necessárias.
2.3 Hibernate: Framework de Persistência de Dados
O Hibernate, renomado framework Java, simplifica a persistência de dados ao introduzir o conceito de mapeamento objeto-relacional (ORM). Essa abordagem eficaz harmoniza estruturas de dados em sistemas orientados a objetos com tabelas em bancos relacionais, permitindo que desenvolvedores manipulem dados em aplicativos Java de maneira simplificada.
Com a capacidade de proporcionar independência de banco de dados, o Hibernate torna o código portável entre diferentes sistemas de gerenciamento. Sua simplicidade na persistência, facilidade de manutenção e suporte à linguagem HQL (Hibernate Query Language) contribuem para um desenvolvimento ágil e legível.
Além disso, o Hibernate simplifica tarefas como inserção, atualização e remoção de registros, apresentando um mecanismo de cache integrado que melhora o desempenho, reduzindo a necessidade de acessos frequentes ao banco de dados.
2.4 Arquitetura REST: Princípios e Restrições
A Arquitetura REST, que significa Representational State Transfer, é uma forma importante de criar serviços web. Ela se baseia em alguns princípios e regras que tornam a comunicação entre diferentes sistemas mais eficiente. No coração desses princípios está a ideia de identificar recursos, que são basicamente as coisas com as quais você quer trabalhar. Cada recurso tem um nome único, que é como um endereço para encontrá-lo na web.
Quando falamos em manipular recursos através de representações, é como se estivéssemos contando a história do recurso de uma maneira que todo mundo possa entender. Usamos formatos como JSON ou XML para transmitir essas histórias. Isso não só ajuda os sistemas a entenderem os dados, mas também torna fácil trocar informações entre diferentes partes de uma aplicação.
Outra parte importante é o uso de operações padrão, como GET, POST, PUT e DELETE. Essas operações são como ações que você pode fazer com um recurso, como criar, ler, atualizar ou excluir. Isso cria uma forma consistente de lidar com as coisas, o que simplifica muito a interação com a API (Interface de Programação de Aplicações) e torna os sistemas que a usam mais robustos e confiáveis.
Então, a Arquitetura REST não é apenas uma técnica, é quase como uma filosofia de design para criar serviços web que sejam eficientes e funcionem bem em diferentes situações. Esses princípios, focados em identificação, representação e ações padronizadas, são a base para construir APIs RESTful que atendem às necessidades de aplicações modernas em um ambiente distribuído.
2.5 Kaizen: Filosofia de Melhoria Contínua
Originária do Japão, a filosofia Kaizen transcende a mera metodologia de gestão para se tornar uma mentalidade arraigada na cultura organizacional. Kaizen, traduzido como “melhoria contínua”, propõe um comprometimento constante com a aprimoração de todos os aspectos de uma organização. O cerne dessa filosofia reside na crença de que pequenas melhorias incrementais, quando aplicadas de forma consistente em todos os níveis da organização, resultam em avanços substanciais e sustentáveis.
Ao aplicarmos os princípios do Kaizen ao contexto específico da gestão de estoque de peças obsoletas, buscamos uma abordagem proativa para a identificação e resolução de desafios inerentes. A filosofia Kaizen nos incentiva a questionar constantemente o status quo, a fim de identificar oportunidades de otimização e eficiência. No contexto do comércio de peças obsoletas entre concessionárias automotivas, onde a agilidade na gestão de estoque é vital, a aplicação do Kaizen é particularmente relevante.
A busca pela melhoria contínua no gerenciamento de peças obsoletas implica na análise minuciosa dos processos existentes, na identificação de gargalos e na implementação de soluções iterativas. O Kaizen não apenas promove a eficiência operacional, mas também cultiva um ambiente onde os colaboradores são capacitados e encorajados a contribuir ativamente para a evolução do sistema.
Assim, ao adotarmos a filosofia do Kaizen, não apenas buscamos aprimorar a gestão de estoque, mas também aspiramos a criar uma cultura organizacional que valoriza a inovação, aprendizado contínuo e a busca incessante pela excelência. Essa mentalidade, enraizada na filosofia Kaizen, é uma força impulsionadora que nos guia na transformação constante, alinhada com as demandas dinâmicas do comércio de peças obsoletas.
2.6 Gestão de Estoque em Concessionárias Automotivas
Na gestão de peças em concessionárias, lidamos com muitas peças diferentes, desde aquelas que fazem o carro funcionar até acessórios específicos. Isso torna a gestão do estoque um desafio, porque precisamos ser estratégicos para garantir que tudo esteja no lugar certo na hora certa.
O mundo dos carros muda rápido, com novas tecnologias e modelos surgindo o tempo todo. Isso torna ainda mais difícil prever quais peças serão necessárias no futuro e evitar ter coisas demais ou de menos. É como um quebra-cabeça complicado que requer análise de dados, tecnologias avançadas e entender bem o que está acontecendo no mercado de carros.
Fazer a gestão de peças não é só sobre evitar perder dinheiro com peças que não são mais usadas, mas também sobre tornar toda a operação mais eficiente. Usamos estratégias como sistemas de rastreamento modernos, previsão de demanda com tecnologia e práticas como “just in time” para lidar com a variedade de peças e atender ao que os clientes precisam no momento certo.
Além disso, é importante ter sistemas de informação bons e garantir que nossa equipe saiba usar essas ferramentas. Isso faz toda a diferença para o sucesso na gestão de peças. Ser ágil para se adaptar a mudanças no mercado e quando novos modelos são lançados também é crucial para ser competitivo na indústria automotiva.
Portanto, ao enfrentar os desafios reais da gestão de peças em concessionárias, precisamos de estratégias que vão além de simplesmente guardar peças. Ideias inovadoras e flexíveis são fundamentais para lidar com os desafios desse setor que está sempre se transformando, enquanto ainda garantimos eficiência e a satisfação contínua dos clientes.
3 DESENVOLVIMENTO
Para que pudéssemos desenvolver uma aplicação que entregasse as necessidades para qual foi desenvolvida, listamos todos os requisitos funcionais que nossa aplicação deverá ter.
Através desses requisitos fomos capazes de dividir o processo de criação em várias etapas. Ficando assim uma melhor visualização de todos os componentes presentes em nosso projeto, conforme etapas abaixo.
3.1 Requisitos Funcionais
Os requisitos funcionais detalham as operações que o sistema deve realizar:
- Efetuar Login (RF_01): Os usuários, sejam usuários ou administradores, devem realizar login para acessar o sistema.
- Alterar Senha (RF_02): Os administradores têm a responsabilidade de alterar as senhas dos clientes, se necessário.
- Cadastrar Usuário (RF_03): Os administradores podem cadastrar usuários, fornecendo informações como ID da concessionária, login e senha.
- Alterar Usuário (RF_04): O administrador pode atualizar informações do usuário.
- Excluir Usuário (RF_05): Usuários inativos podem ser removidos pelo administrador.
- Alterar Peças (RF_07): Os usuários podem alterar informações de peças já cadastradas, como quantidade e valor em seu dealer correspondente.
- Excluir Peça (RF_09): Os clientes podem excluir informações de peças já cadastradas.
- Listar Peças por Concessionárias (RF_12): O sistema permite a listagem de todas as peças por concessionária.
- Listar Peças por part number (RF_12): O sistema permite a listagem de todas as peças com o part number corresponde.
3.2 Banco de Dados
Com base nos requisitos identificados, elaboramos um diagrama de entidade-relacionamento que serviu como fundamento para a criação do banco de dados. Este diagrama proporcionou uma análise minuciosa das entidades, seus atributos específicos e as relações entre elas.
Figura 1 – Diagrama Entidade Relacionamento
Fonte: Elaborado pelo autor.
Abaixo estão os comandos SQL usados para criar uma entidade e definir suas propriedades no banco de dados.
Figura 2 – Comando SQL para a criação do Banco de dados
Fonte: Elaborado pelo autor.
3.3 Organização das Classes na Arquitetura REST
Durante esta fase, procedemos com criação das classes fundamentais para a aplicação, seguindo os princípios da arquitetura REST. Para promover uma estrutura organizada, as classes foram distribuídas em pacotes distintos, cada um desempenhando um papel específico na arquitetura.
Ao organizar as classes dessa maneira, seguimos as boas práticas da arquitetura REST, promovendo uma separação clara de responsabilidades e facilitando a manutenção e escalabilidade do sistema. Este método estruturado proporciona uma base sólida para o desenvolvimento de uma aplicação robusta e eficiente.
Figura 3 – Organização dos pacotes da API
Fonte: Elaborado pelo autor.
3.4 Domain:
Dentro do pacote ‘domain’, encontram-se as classes de entidades e seus DTO´s, Essas classes definem a estrutura dos dados manipulados pela aplicação.
As classes de entidades representam os objetos fundamentais do sistema, os elementos centrais, como Usuário, Concessionária e Peça. Cada classe reflete as propriedades e comportamentos essenciais desses objetos.
Figura 4 – Organização pacote Domain
Fonte: Elaborado pelo autor.
3.4.1 Classe Parts
A classe Parts foi construída incorporando atributos essenciais como Id, Part Number, Quantidade e Valor. Vale ressaltar que a integridade dessa classe é mantida por meio de uma chave estrangeira associada ao Id da entidade Dealer, cuja coluna é denominada dealer_cod.
Em busca de uma implementação mais refinada e elegante, adotou-se a biblioteca Lombok. Esta ferramenta, por meio de anotações estratégicas como @Setter, @Getter, @NoArgsConstructor e @AllArgsConstructor, automatiza a geração de construtores, setters e getters. Tal abordagem não apenas simplifica o código, mas também eleva o nível de clareza e concisão na representação das entidades.
Assim, o resultado é uma estrutura de classe que alia a rigidez conceitual necessária com a praticidade oferecida pela automação, proporcionando uma base sólida para a manipulação de dados no contexto do projeto.
Figura 5 – Classe Parts da API
Fonte: Elaborado pelo autor.
3.4.2 Classe Dealer
A classe Dealer foi construída com atributos fundamentais para sua funcionalidade. Entre esses, destacam-se elementos cruciais como o atributo “cod”, que desempenha o papel de identificador único da entidade, além de nome e endereço, essenciais para caracterizar de forma abrangente as informações associadas a um revendedor.
Figura 6 – Classe Dealer da API
Fonte: Elaborado pelo autor.
3.4.3 Classe Users
A classe Users foi configurada para implementar a interface UserDetails, desempenhando o papel de armazenar informações do usuário. Essa implementação permitiu encapsular dados não relacionados à segurança em Authentication objects, facilitando a gestão eficiente durante os processos de autenticação. A integração da classe Users com a interface UserDetails foi utilizado para centralizar e gerenciar informações do usuário de forma segura e modular, contribuindo para a eficácia do sistema de autenticação.
Figura 7 – Classe Users da API
Fonte: Elaborado pelo autor.
Na classe Users, foram implementados métodos essenciais que integram a interface UserDetails, desempenhando um papel crucial no contexto da autenticação e autorização do usuário. Cada um desses métodos contribui para a definição do perfil do usuário no sistema, seguindo os princípios estabelecidos pela interface mencionada. Abaixo foram listadas as funcionalidades de cada método:
- public Collection<? extends GrantedAuthority> getAuthorities()
- Retorna as autoridades concedidas ao usuário, que no caso da nossa aplicação são “ADMIN” e “USER”.
- public String getUsername();
- Retorna o nome de usuário usado para autenticar o usuário.
- public boolean isAccountNonExpired();
- Indica se a conta do usuário expirou.
- public boolean isAccountNonLocked();
- Indica se o usuário está bloqueado ou desbloqueado.
- public boolean isCredentialsNonExpired();
- Indica se as credenciais do usuário (senha) expiraram.
- public boolean isEnabled():
- Indica se o usuário está habilitado ou desabilitado.
Figura 8 – Métodos da Classe Users
Fonte: Elaborado pelo autor.
3.4.4 DTO
Dentro dos pacotes de cada entidade foram criados DTO, objetos projetados para transferir dados entre camadas do sistema de maneira eficiente. Eles encapsulam informações específicas necessárias para uma operação, evitando a transferência desnecessária de dados e melhorando o desempenho da aplicação.
- DealerDTO;
- Responsável em encapsular os dados da classe dealer como name, cod e endereço.
Figura 9 – DealerDTO
Fonte: Elaborado pelo autor.
- PartsRequest;
- Responsável em encapsular os dados da classe parts para as requisições, ela traz os dados como código da peça, quantidade e valor.
Figura 10 – PartsRequest DTO
Fonte: Elaborado pelo autor.
- PartsResponse;
- Responsável em encapsular os dados da classe parts para as respostas , ela traz os dados como código da peça, quantidade e valor.
- Traz o método PartsResponse que retorna os dados como código da peça, quantidade, valor e dealer.
Figura 11 – PartsResponse DTO
Fonte: Elaborado pelo autor.
- Login:
- Responsável em encapsular os dados da classe Users relacionado ao login, ela traz os dados como login, role e password.
Figura 12 – Login DTO
Fonte: Elaborado pelo autor.
- LoginResponse:
- Responsável em encapsular os dados da classe Users para respostas relacionadas ao login, ela traz o token de acesso.
Figura 13 – Login Response DTO
Fonte: Elaborado pelo autor.
- Register:
- Responsável em encapsular os dados da classe Users relacionado a criar novo usaurio, ela traz os dados como login, role, password e dealer.
Figura 14 – Register DTO
Fonte: Elaborado pelo autor.
3.5 Controladores:
Dentro do pacote ‘controller’, encontram-se as classes encarregadas de receber e processar as requisições HTTP. Cada controlador tem a função de mapear endpoints específicos, estabelecendo a conexão entre as requisições dos clientes e as operações correspondentes no sistema. Essa estrutura organiza de forma eficiente o tratamento das interações externas, permitindo uma gestão clara e especializada das diversas funcionalidades disponibilizadas pela aplicação.
3.5.1 Classe AuthenticationController:
A classe AuthenticationController é um controlador Spring que gerencia as operações relacionadas à autenticação e autorização. Essa classe é responsável por lidar com solicitações relacionadas ao login, registro de usuários e registro de revendedores, conectando as requisições HTTP às operações correspondentes na aplicação.
Figura 15 – Classe AuthenticationController da API
Fonte: Elaborado pelo autor.
Os métodos presentem na classe AuthenticationController, contribuem de maneira única para a integridade e funcionalidade do sistema de autenticação e autorização da nossa aplicação, sendo eles:
- Método login;
- Endpoint: /login
- Recebe uma requisição POST contendo dados de login (Login).
- Cria um objeto UsernamePasswordAuthenticationToken com as credenciais fornecidas.
- Autentica as credenciais usando authenticationManager.
- Gera um token de autenticação usando tokenService.
- Retorna uma resposta bem-sucedida contendo o token.
- Método registerUser:
- Endpoint: /register/user
- Recebe uma requisição POST contendo dados de registro de usuário (Register).
- Verifica se o login já está em uso e retorna uma resposta de erro, se necessário.
- Encripta a senha usando BCrypt.
- Obtém o revendedor associado ao código fornecido.
- Se o revendedor existe, cria um novo usuário (Users) e o salva no repositório.
- Retorna uma resposta bem-sucedida.
- Método registerDealer:
- Endpoint: /register/dealer
- Recebe uma requisição POST contendo dados de registro de revendedor (DealerDTO).
- Verifica se o revendedor já está cadastrado e retorna uma resposta de erro, se necessário.
- Cria um novo objeto Dealer com base nos dados fornecidos.
- Salva o revendedor no repositório.
- Retorna uma resposta bem-sucedida.
Figura 16 – Métodos Classe AutheticationController
Fonte: Elaborado pelo autor.
3.5.2 Classe Parts Controller
A classe PartsController se destaca por ser responsável pela gestão e manipulação de informações relacionadas a peças na nossa aplicação. Como um controlador Spring, ela interage com solicitações HTTP, conectando-se diretamente aos serviços e ao repositório de peças.
Figura 17 – Classe PartsController da API
Fonte: Elaborado pelo autor.
Abaixo está a lista de metodos que foram implementados na classe:
- Método getAllParts:
- Endpoint: /parts
- Obtém todas as peças por meio do serviço partsService.
- Retorna uma resposta bem-sucedida com a lista de peças, se existirem.
- Caso contrário, retorna uma resposta indicando que não foram encontradas peças.
- Método getAllPartsByPartNumber:
- Endpoint: /parts/partNumber={partNumber}
- Obtém todas as peças com base no número da peça fornecido por meio do serviço partsService.
- Retorna uma resposta bem-sucedida com a lista de peças correspondentes, se existirem.
- Caso contrário, lança uma exceção indicando que não foram encontradas peças.
- Método getAllPartsByDealerCod:
- Endpoint: /parts/dealerCod={DealerCod}
- Obtém todas as peças associadas ao código do revendedor por meio do serviço partsService.
- Retorna uma resposta bem-sucedida com a lista de peças, se existirem.
- Caso contrário, lança uma exceção indicando que não foram encontradas peças.
- Método createParts:
- Endpoint: /parts
- Recebe uma requisição POST contendo dados de uma nova peça (PartsRequest).
- Cria a nova peça utilizando o serviço partsService.
- Retorna uma resposta indicando que a peça foi criada com sucesso.
- Método updateParts:
- Endpoint: /parts/update
- Recebe uma requisição PUT contendo dados de uma peça a ser atualizada (PartsRequest).
- Atualiza a peça usando o serviço partsService.
- Retorna uma resposta bem-sucedida com a peça atualizada, se a operação for concluída com sucesso.
- Caso contrário, lança uma exceção indicando que a peça não foi encontrada.
- Método delete:
- Endpoint: /parts/delete={id}
- Recebe uma requisição DELETE para excluir uma peça com base no ID fornecido.
- Verifica se a peça existe no repositório e, se sim, a exclui.
- Retorna uma resposta bem-sucedida indicando que a peça foi removida, se a operação for concluída com sucesso.
- Caso contrário, retorna uma resposta indicando que a peça não foi encontrada.
Figura 18 Métodos da classe PartsController 1/2
Fonte: Elaborado pelo autor.
Figura 19 – Métodos da classe PartsController 2/2
Fonte: Elaborado pelo autor.
3.6 Repositories
As classes do pacote ‘repository’ lidam com a interação entre a aplicação e o banco de dados. Utilizando o Spring Data JPA, esses repositórios simplificam operações básicas de CRUD (Create, Read, Update, Delete) no banco de dados associado à entidade.
3.6.1 Classe PartsRepository
A classe PartsRepository além de herdar os métodos básicos CRUD, foi implementado métodos adicionais para recuperar listas de peças com base no número da peça e no código do revendedor.
Utilizamos tambem a anotação @query que permite a definição de consultas personalizadas usando JPQL (Java Persistence Query Language), neste caso, para buscar o ID de uma peça com base no número da peça e no código do revendedor.
Figura 20 – Classe PartsRepository
Fonte: Elaborado pelo autor.
3.6.2 Classe UsersRepository
Além dos métodos herdados para operações básicas de CRUD, a classe define métodos específicos para interações com usuários no banco de dados.
O método findByLogin utiliza uma consulta padrão para recuperar detalhes do usuário com base no nome de login. Por sua vez, o método personalizado findDealerByLogin usa uma consulta JPQL para extrair o revendedor associado a um determinado login de usuário.
Figura 21 – Classe UsersRepository
Fonte: Elaborado pelo autor.
3.6.3 Classe DealerRepository
A classe DealerRepository é responsável por simplificar e organizar o acesso aos dados relacionadas à entidade Dealer .
Figura 22 – Classe DealerRepository
Fonte: Elaborado pelo autor.
3.7 Services:
No pacote ‘service’, localizam-se as classes que contêm a lógica de negócios da aplicação. Essas classes são responsáveis por executar operações específicas solicitadas pelos controladores, conectando a camada de apresentação à camada de persistência.
3.7.1 Classe AuthorizationService
Sendo uma implementação de UserDetailsService, ela integra-se ao mecanismo de segurança do Spring, fornecendo funcionalidades específicas para carregar detalhes do usuário durante o processo de autenticação.
O método loadUserByUsername é implementado para recuperar detalhes do usuário com base no nome de login. Ele utiliza o UsersRepository para realizar essa operação e retorna um objeto UserDetails. Caso o login não seja encontrado, uma exceção do tipo UsernameNotFoundException é lançada.
Figura 23 – Classe AuthorizationService
Fonte: Elaborado pelo autor.
3.7.2 Classe PartsRepository
A classe PartsService, anotada como @Service, desempenha um papel fundamental na lógica de negócios relacionada às peças da aplicação. Ela interage com os repositórios de Parts e Users para fornecer funcionalidades específicas relacionadas à gestão de peças.
Os principais métodos desta classe incluem:
- getAllParts:
- Obtém todas as peças no sistema utilizando o método findAll do PartsRepository.
- getAllPartsByPartNumber:
- Obtém todas as peças com base em um número de peça específico usando o método findAllByPartNumber do PartsRepository.
- getAllPartsByDealerCod:
- Obtém todas as peças associadas a um código de revendedor específico utilizando o método findAllByDealerCod do PartsRepository.
- createParts:
- Cria uma nova peça com base nos dados fornecidos por meio de um objeto PartsRequest.
- Utiliza o securityFilter para obter o login do usuário atual.
- Busca o revendedor associado ao login por meio do usersRepository.
- Cria a nova peça associada ao revendedor.
- Salva a peça no banco de dados utilizando o método save do PartsRepository.
- Retorna a peça recém-criada.
Figura 24 – Classe PartsService
Fonte: Elaborado pelo autor.
3.7.3 Classe RequestExceptionHandler
A classe RequestExceptionHandler é anotada como @RestControllerAdvice e atua como um componente responsável por lidar com exceções lançadas durante as requisições HTTP. O método threat404 é decorado com a anotação @ExceptionHandler(EntityNotFoundException.class) para tratar exceções do tipo EntityNotFoundException.
Quando uma exceção do tipo EntityNotFoundException é lançada durante o processamento de uma requisição, o método threat404 é invocado, resultando em uma resposta HTTP com status de erro (bad request) e uma mensagem indicando que o dado não foi encontrado. Essa abordagem centralizada para o tratamento de exceções contribui para a consistência e clareza nas respostas da API em situações de não localização de entidades.
Figura 25 – Classe RequestExceptionHandler
Fonte: Elaborado pelo autor.
3.8 Security
O pacote ‘security’ abrange as classes relacionadas à segurança da aplicação. Aqui, implementamos medidas como autenticação e autorização, garantindo o acesso seguro aos recursos e protegendo informações sensíveis.
Figura 26 – Organização pacote Security
Fonte: Elaborado pelo autor
3.8.1 Classe SecurityConfig
A classe SecurityConfig representa a configuração de segurança da aplicação Spring. Ela é anotada com @Configuration e @EnableWebSecurity, indicando que é responsável por definir as políticas de segurança para a aplicação. Aqui está um resumo dos principais elementos desta classe:
- Método securityFilterChain:
- Configura as políticas de segurança HTTP.
- Desabilita a proteção CSRF.
- Define que a criação de sessão é sem estado (STATELESS).
- Especifica as autorizações para diferentes endpoints, permitindo o acesso sem autenticação para alguns (por exemplo, login e registro) e exigindo a função “ADMIN” para outros (por exemplo, operações relacionadas a peças).
- Adiciona o securityFilter antes do UsernamePasswordAuthenticationFilter.
- Método authenticationManager:
- Configura o AuthenticationManager para a aplicação.
- Utiliza o AuthenticationConfiguration para obter o gerenciador de autenticação.
- Método passwordEncoder:
- Configura o PasswordEncoder para a aplicação.
- Utiliza o algoritmo BCrypt para codificar senhas de forma segura.
- Essa configuração estabelece as regras de segurança da aplicação, determinando como as requisições são autorizadas e autenticadas. A utilização do securityFilter e a definição de políticas específicas para endpoints contribuem para um controle preciso e seguro do acesso aos recursos da aplicação.
Figura 27 – Classe SecurityConfig
Fonte: Elaborado pelo autor.
3.8.2 Classe SecurityFilter
A classe SecurityFilter é um componente Spring anotado com @Component e estende OncePerRequestFilter, o que significa que será executado uma vez por cada requisição HTTP.
Ela é responsável por gerenciar a validação e a autenticação de tokens JWT presentes nos cabeçalhos das requisições HTTP.
Este filtro desempenha um papel fundamental na integração da autenticação JWT com o sistema de segurança da aplicação Spring, garantindo a validação adequada dos tokens e a atualização do contexto de segurança.
- Método doFilterInternal:
- Intercepta cada requisição para verificar a presença de um token JWT no cabeçalho “Authorization”.
- Valida o token usando o serviço TokenService.
- Obtém o login do usuário a partir do token validado.
- Recupera as informações do usuário do repositório usando o UsersRepository.
- Atualiza o contexto de segurança (SecurityContextHolder) com as informações do usuário autenticado.
- Método recoverToken:
- Recupera o token JWT do cabeçalho “Authorization” da requisição.
- Atributo loadUser:
- Armazena o login do usuário autenticado, permitindo seu acesso fora do filtro.
Figura 28- Classe SecurityFilter
Fonte: Elaborado pelo autor.
3.8.3 Classe TokenService
A classe TokenService é anotada como @Service e é responsável pela geração e validação de tokens JWT (JSON Web Tokens) no contexto da segurança da aplicação. Aqui está um resumo das principais funcionalidades desta classe:
- Atributo secret:
- Armazena a chave secreta necessária para assinar e verificar os tokens JWT. O valor é lido a partir das configurações da aplicação.
- Método generateToken:
- Gera um token JWT utilizando a biblioteca jjwt.
- Utiliza o algoritmo HMAC256 para assinar o token.
- Define o emissor (“issuer”) como “inventory-api” e o assunto (“subject”) como o login do usuário.
- Define a data de expiração do token como duas horas a partir do momento da geração.
- Método validateToken:
- Valida a integridade e a assinatura de um token JWT.
- Retorna o login do usuário contido no token se a validação for bem-sucedida; caso contrário, retorna uma string vazia.
- Método genExpirationDate:
- Gera a data de expiração dos tokens, configurada para duas horas a partir do momento da geração.
- Essa classe desempenha um papel fundamental na geração segura de tokens JWT para autenticação, permitindo a criação e validação de tokens no contexto da segurança da aplicação Spring.
Figura 29 – TokenService
Fonte: Elaborado pelo autor
4 RESULTADOS
Para conduzir os testes em nossa aplicação, utilizamos o software Insomnia, permitindo a execução de requisições HTTP de diversos tipos e simulação de interações de usuários.
4.1 Login:
A aplicação realiza verificações em todas as requisições para garantir a presença e validade do token de acesso, além da compatibilidade das permissões com as do usuário. Os tokens são gerados a partir das credenciais de login, fornecidas por meio de um arquivo JSON contendo dados de usuário e senha para validação do acesso.
Figura 30 – Requisição de Login bem sucedida
Fonte: Elaborado pelo autor.
Na verificação do processo de login, identificamos que, em situações em que o usuário não existe ou a senha fornecida está incorreta, a aplicação retorna um código 403 – Forbidden. Essa abordagem visa garantir a segurança e proteção de informações sensíveis, restringindo o acesso não autorizado.
Figura 31 – Requisição de Login mal sucedida
Fonte: Elaborado pelo autor.
4.2 Registro de Peça:
Para efetuar o registro de uma peça, a aplicação aguarda uma requisição do tipo POST, acompanhada de um arquivo JSON contendo os dados da peça, tais como partnumber, quantidade e valor. É importante ressaltar que, ao realizar o registro de uma peça, ela ficará automaticamente vinculada ao Dealer do usuário que está efetuando o cadastro. Essa restrição impede o cadastro de peças para outros Dealers, garantindo a integridade e organização das informações relacionadas a cada concessionária..
Figura 32 – Registro de peça
Fonte: Elaborado pelo autor.
4.3 Alterar peça:
A operação de alteração de peça requer a apresentação de um token válido, fornecendo autenticação para a solicitação. Além disso, é necessário enviar um arquivo JSON contendo as informações relevantes para a peça que se deseja modificar, incluindo o partnumber, a quantidade e o valor.
Figura 33 – Alteração de peça
Fonte: Elaborado pelo autor.
4.4 Listar Peças:
Ao realizar uma requisição do tipo GET para o endpoint “/parts” e fornecer um token válido, a aplicação retorna todas as peças cadastradas no banco de dados. Essa funcionalidade permite uma visão abrangente de todas as peças disponíveis no sistema, promovendo transparência e facilitando o processo de busca por parte dos usuários.
Figura 34 – Listar peças
Fonte: Elaborado pelo autor.
4.5 Listar Peças por Dealer:
Ao receber uma requisição HTTP do tipo GET contendo o código do Dealer a ser pesquisado, a aplicação retorna todas as peças associadas a esse Dealer específico. Essa funcionalidade visa proporcionar uma visão detalhada do inventário de peças de cada concessionária, facilitando a gestão e identificação de itens disponíveis para comercialização.
Figura 35 – Listar Peças por Dealer
Fonte: Elaborado pelo autor.
4.6 Listar Peças por PartNumber:
Ao receber uma requisição HTTP do tipo GET contendo o código da peça, conhecido como PartNumber, a aplicação retorna todas as peças associadas a esse identificador específico. Essa funcionalidade proporciona uma maneira eficiente de visualizar todas as variações de uma determinada peça, facilitando a busca e o gerenciamento desses componentes.
Figura 36 – Listar Peça por PartNumber
Fonte: Elaborado pelo autor.
4.7 Deletar Peça:
Ao realizar uma requisição HTTP do tipo DELETE, fornecendo o ID da peça a ser excluída, a aplicação irá remover a peça do sistema, desde que esteja associada ao dealer do usuário que efetuou a requisição. Essa medida garante a segurança e a integridade das informações, permitindo exclusões apenas dentro do contexto do dealer específico, evitando a manipulação indevida de dados entre diferentes concessionárias.
Figura 37 – Deletar peça
Fonte: Elaborado pelo autor.
4.8 Cadastrar Usuário:
A realização de requisições para o cadastro de usuários está condicionada à permissão de administrador. Somente usuários com essa permissão têm autorização para efetuar o cadastro. A aplicação espera receber um objeto JSON contendo os atributos necessários, como login, senha, papel (role) e dealer. Essa abordagem visa garantir a segurança e o controle adequado sobre o cadastro de usuários, limitando essa funcionalidade a perfis administrativos.
Figura 38 – Cadastro de usuario
Fonte: Elaborado pelo autor.
4.9 Cadastrar Dealer:
Para realizar o cadastro de um dealer, é necessário fornecer um arquivo JSON contendo as informações essenciais, como nome, endereço e código do dealer. Esses dados são cruciais para identificar e categorizar o novo dealer dentro do sistema.
Figura 39 – Cadastro de Dealer bem sucedido
Fonte: Elaborado pelo autor.
Ao receber a requisição de cadastro, a aplicação verifica se o token associado à solicitação possui permissões de administrador. Essa verificação é fundamental para garantir que apenas usuários autorizados possam executar operações sensíveis, como a adição de novos dealers.
Figura 40 – Usuario sem permissão
Fonte: Elaborado pelo autor.
5 CONCLUSÃO
A aplicação demonstrou-se altamente eficaz na proposta apresentada, fornecendo uma API capaz de manipular o estoque de peças podendo assim contribuir para a otimização do comercio de peças obsoletas.
O mecanismo de segurança baseado em tokens revelou-se particularmente eficiente, permitindo a criação de várias camadas de autorização para os usuários. Sendo uma API REST, ela oferece a flexibilidade de escalabilidade, possibilitando a implementação de novas funções em versões futuras. Como sugestão para uma próxima atualização, poderia ser considerada a implementação de um serviço de mensageria para facilitar a interação entre os usuários. Isso adicionaria uma camada adicional de funcionalidade à aplicação, promovendo uma experiência mais colaborativa e integrada.
REFERENCIAS BIBLIOGRÁFICAS
BRIALES, Julio Aragon. Melhoria contínua através do kaizen: Estudo de caso DaimlerChrysler do Brasil. 2005. 156f. Dissertação (Mestrado em Sistema de Gestão) Programa de Mestrado em Sistema de Gestão pela Qualidade Total. Universidade Federal Fluminense. Niterói. 2005.
BRITO, M. Spring Boot Da API REST aos Microservices – 4ª Edição, 2023. E-book(55p)Disponível em: https://www.michellibrito.com/ebook-spring-boot-3-microservices . Acesso em: 15 nov.2023.
CANGUÇU, R. O que são Requisitos Funcionais e Requisitos Não Funcionais?. Disponível em: https://codificar.com.br/requisitos-funcionais-nao-funcionais Acesso em: 17 ago.2023.
CASTROS, J. F. B. Introdução à engenharia de requisitos. In: XV Congresso da Sociedade Brasileira de Computação, JAI’95, Canela, RS, Brasil, 1995, 43p..
COUTINHO, T. Alcance a melhoria contínua por meio da metodologia Kaizen!. Disponível em: https://www.voitto.com.br/blog/artigo/o-que-e-kaizen. Acesso em: 17 ago.2023.
DE PAULA, R. W. A. API REST e RESTful: entenda de uma vez por todas a diferença entre eles, 2020. Disponível em: https://4success.com.br/api-rest-e-restful/. Acesso em: 15 nov.2023.
ERROR Handling for REST with Spring. Baeldung, 2022 Disponível em:
https://www.baeldung.com/exception-handling-for-rest-with-spring . Acesso em: 23 set.2023.
FOWLER, M. Richardson Maturity Model, 2010. Disponível em: https://martinfowler.com/articles/richardsonMaturityModel.html . Acesso em: 15 nov.2023.
JUNIOR, R. Modelo de maturidade de Richardson para APIs REST, 2020. Disponível em: https://rivaildojunior.medium.com/modelo-de-maturidade-de-richardson-para-apis-rest-8845f93b288 . Acesso em: 15 nov.2023.
LOUZADA, P. O Sistema Toyota de Produção e o Controle de Quantidade. Disponível em: https://www.fm2s.com.br/controle-de-quantidade. Acesso em17 ago.2023..
MALAQUIAS, M. Projeto Lombok: Escrevendo menos código em Java. Disponível em:
https://imasters.com.br/back-end/projeto-lombok-escrevendo-menos-codigo-em-java. Acesso em: 23 set.2023.
MILOSEVIC, D. REST Security With JWT Using Java and Spring Security. Disponível em:
https://www.toptal.com/java/rest-security-with-jwt-spring-security-and-java . Acesso em: 23 set.2023.
PIRES, J. O que é API? REST e RESTful? Conheça as definições e diferenças! 2016.Disponível em: https://becode.com.br/o-que-e-api-rest-e-restful/ . Acesso em: 20 out.2023.
SPRING, @RequestParam vs @PathVariable Annotation. Baeldung, 2022 Disponível em:
https://www.baeldung.com/spring-requestparam-vs-pathvariable . Acesso em: 23 set.2023.
SRIDHAR, J. Java String Format Examples. 2021.Disponível em:
https://dzone.com/articles/java-string-format-examples . Acesso em: 20 out.2023.
SUBRAMANIAM, P. API REST – Modelagem de Recursos, 2014. Disponível em: https://www.thoughtworks.com/pt-br/insights/blog/rest-api-design-resource-modeling . Acesso em: 15 nov.2023.
Wellton Manopelli – [1] Graduando do Curso de Engenharia da Computação da Universidade de Araraquara- UNIARA. Araraquara-SP. E-mail: wrmanopelli@uniara.edu.br.
[Felipe Diniz Dallilo – 2] Orientador. Docente Curso de Engenharia da Computação da Universidade de Araraquara- UNIARA. Araraquara-SP. E-mail: fflorian@uniara.edu.br.
[Fabiana Florian – 3] Coorientador. Docente Curso de Engenharia da Computação da Universidade de Araraquara- UNIARA. Araraquara-SP. E-mail: fddallilo@uniara.edu.br.1