Skip to content

[WiP] 🚧 Projeto simplificado de um autenticador de usuários utilizando JWT, Spring Boot, Spring Security, JPA, MySQL, SOLID e Clean Architecture.

Notifications You must be signed in to change notification settings

alonsofritz/simplified-authenticator-spring

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Autenticador Simplificado

Projeto simplificado de um autenticador de usuários utilizando JWT, Spring Boot, Spring Security, JPA, MySQL, SOLID e Clean Architecture.

ĂŤndice

  1. Estrutura de Pastas

    1. Diferença entre Services na Application e Domain
    2. Diferença entre Mappers da Adapters e da Application
    3. Diferença entre Use Cases e Services da Application
    4. Resumo das Diferenças
  2. Helper

    1. Gerar chave privada
    2. Gerar chave pĂşblica a partir da chave privada

Estrutura de Pastas

src
└── main
    └── java
        └── com
            └── seu
                └── projeto
                    ├── application
                    │   ├── dto                 // Data Transfer Objects
                    │   ├── exceptions          // Exceções específicas da aplicação
                    │   ├── services            // Serviços da camada de aplicação
                    │   ├── usecases            // Casos de uso (interações da aplicação)
                    │   └── mappers             // Mapeadores entre entidades e DTOs
                    │
                    ├── domain
                    │   ├── entities            // Entidades de domínio
                    │   ├── repositories         // Interfaces de repositórios
                    │   ├── services            // Lógica de negócios
                    │   ├── specifications       // Especificações de domínio (predicados)
                    │   └── events               // Eventos de domínio
                    |   └── valueobjects        // Objetos de valor
                    |   └── factories            // Fábricas de entidades
                    │
                    ├── adapters
                    │   ├── controllers          // Controladores (REST, gRPC, etc.)
                    │   ├── gateways             // Interfaces para sistemas externos
                    │   ├── presenters           // Formatação de dados para saída
                    │   └── mappers              // Mapeadores de entidades para DTOs (separados dos da aplicação)
                    │
                    └── infra
                        ├── configuration        // Configurações gerais (Spring, segurança, etc.)
                        ├── database             // Configuração de banco de dados (JPA, JDBC)
                        │   ├── entities         // Entidades específicas para o banco de dados
                        │   ├── repositories      // Implementações dos repositórios
                        │   └── migrations        // Scripts de migração do banco de dados
                        │
                        ├── messaging            // Configuração de mensageria (RabbitMQ, Kafka, etc.)
                        ├── security             // Configuração de segurança (Spring Security, autenticação)
                        ├── logging              // Configuração de logging (Logback, SLF4J, etc.)
                        ├── cache                // Configuração de cache (Redis, Memcached)
                        └── external             // Integrações com serviços externos (APIs, SDKs)

1. application

  • dto: ContĂ©m os Data Transfer Objects, que sĂŁo objetos usados para transportar dados entre diferentes camadas da aplicação, especialmente entre a camada de apresentação (adaptadores) e a camada de aplicação. Eles geralmente nĂŁo contĂŞm lĂłgica de negĂłcios, mas sim estruturas de dados simples.
  • exceptions: Exceções especĂ­ficas que podem ser lançadas durante a execução dos casos de uso ou serviços. Isso ajuda a centralizar o tratamento de erros.
  • services: Serviços da camada de aplicação que orquestram a lĂłgica de negĂłcios e a interação entre os casos de uso. Eles podem chamar mĂşltiplos casos de uso e coordenar suas operações.
  • usecases: Casos de uso que representam interações especĂ­ficas que os usuários podem ter com a aplicação. Cada caso de uso Ă© responsável por uma ação ou tarefa, encapsulando a lĂłgica necessária para completá-la.
  • mappers: Mapeadores que transformam entidades de domĂ­nio em DTOs e vice-versa. Eles sĂŁo Ăşteis para separar a lĂłgica de conversĂŁo e manter os casos de uso mais limpos.

2. domain

  • entities: ContĂ©m as entidades de domĂ­nio, que sĂŁo representações dos objetos de negĂłcio e contĂŞm a lĂłgica relacionada ao estado e ao comportamento desses objetos.
  • repositories: Interfaces que definem operações de acesso a dados para as entidades de domĂ­nio. Os repositĂłrios abstraem a lĂłgica de persistĂŞncia e permitem que a aplicação interaja com a camada de dados.
  • services: LĂłgica de negĂłcios que nĂŁo se encaixa em uma entidade especĂ­fica. Por exemplo, serviços que realizam operações complexas envolvendo mĂşltiplas entidades. Esses serviços podem incluir regras de negĂłcios que sĂŁo fundamentais para a lĂłgica da aplicação.
  • specifications: Predicados ou critĂ©rios que podem ser usados para consultar entidades. Eles ajudam a separar a lĂłgica de consulta da lĂłgica de domĂ­nio.
  • events: Representam eventos que ocorrem no domĂ­nio, como alterações de estado. Eles podem ser usados para implementar padrões como Event Sourcing ou CQRS.
  • valueobjects: Objetos que representam valores (como moeda ou endereço) e nĂŁo tĂŞm identidade prĂłpria. Eles sĂŁo imutáveis e geralmente sĂŁo usados para encapsular regras de validação e lĂłgica.
  • factories: Classes responsáveis pela criação de entidades ou objetos complexos, encapsulando a lĂłgica de construção.

3. adapters

  • controllers: Controladores que recebem as solicitações do usuário e orquestram as chamadas aos casos de uso apropriados. Eles tambĂ©m formatam as respostas a serem enviadas de volta ao cliente.
  • gateways: Interfaces que abstraem a comunicação com sistemas externos, como APIs ou serviços de terceiros. Eles permitem que a aplicação se integre com serviços externos sem acoplamento forte.
  • presenters: Formatação de dados para saĂ­da. Eles preparam os dados que serĂŁo retornados ao usuário, possivelmente convertendo dados de domĂ­nio em formatos mais amigáveis.
  • mappers: Mapeadores especĂ­ficos para conversĂŁo de entidades em DTOs (separados da aplicação). Esses mapeadores sĂŁo usados para transformar os dados que vĂŞm do banco ou de outras fontes em estruturas que a camada de apresentação pode usar.

4. infra

  • configuration: Configurações gerais da aplicação, como as configurações do Spring, segurança, etc. Esse pacote pode conter classes de configuração e inicialização.
  • database: Configuração especĂ­fica de banco de dados. Pode conter entidades JPA, repositĂłrios concretos que implementam as interfaces definidas na camada de domĂ­nio, e scripts de migração.
  • messaging: Configuração de sistemas de mensageria, como RabbitMQ ou Kafka. Isso pode incluir tĂłpicos, filas e configurações para a publicação e assinatura de mensagens.
  • security: Configurações de segurança, incluindo autenticação e autorização usando frameworks como o Spring Security.
  • logging: Configuração de logging, como integração com Logback ou SLF4J, permitindo a captura de logs da aplicação.
  • cache: Configuração de sistemas de cache, como Redis ou Memcached, para otimizar o desempenho da aplicação.
  • external: Integrações com serviços externos, como APIs ou SDKs. Esse pacote pode conter classes e configurações para se conectar e interagir com serviços fora da aplicação.

Diferença entre Services na Application e Domain

  • Services da Application:

    • Responsáveis por orquestrar a lĂłgica de interação entre os casos de uso. Eles lidam com a lĂłgica de aplicação, como controle de fluxo, validação de entrada e coordenação de chamadas a mĂşltiplos casos de uso.
    • Exemplo: Um serviço de aplicação pode ser responsável por validar um usuário, chamar o caso de uso de registro e, em seguida, gerar um token.
  • Services da Domain:

    • ContĂŞm a lĂłgica de negĂłcios que está intrinsecamente relacionada Ă s entidades de domĂ­nio. Eles podem incluir operações complexas que envolvem regras de negĂłcio, mas nĂŁo estĂŁo diretamente ligadas ao controle de fluxo da aplicação.
    • Exemplo: Um serviço de domĂ­nio pode ter a responsabilidade de calcular o preço total de um pedido, considerando regras especĂ­ficas de negĂłcio, como descontos ou promoções.

Diferença entre Mappers da Adapters e da Application

Mappers da Application

  • Responsabilidade: Os mappers da camada application sĂŁo responsáveis por transformar entidades de domĂ­nio em Data Transfer Objects (DTOs) e vice-versa. Eles atuam na conversĂŁo de dados que serĂŁo usados internamente pela aplicação, garantindo que as entidades de domĂ­nio sejam representadas adequadamente nas interações de uso dos casos.
  • Objetivo: O objetivo principal Ă© facilitar a comunicação entre a lĂłgica de negĂłcios (casos de uso) e a apresentação (controladores), mantendo a separação de preocupações e a clareza na manipulação dos dados.
  • Exemplo: Se um caso de uso precisa de um DTO para receber dados de entrada de um controlador, o mapper da aplicação converte esse DTO em uma entidade de domĂ­nio.
public class UserMapper {
    public static User toEntity(UserDTO userDTO) {
        return new User(userDTO.getUsername(), userDTO.getPassword());
    }

    public static UserDTO toDTO(User user) {
        return new UserDTO(user.getUsername());
    }
}

Mappers da Adapters

  • Responsabilidade: Os mappers da camada adapters sĂŁo encarregados de adaptar os dados entre a camada de apresentação (como uma API REST ou um serviço gRPC) e a estrutura interna da aplicação. Eles garantem que as informações sejam formatadas corretamente para serem enviadas ou recebidas de clientes ou sistemas externos.
  • Objetivo: O foco está na integração com o mundo exterior, ajustando a forma como os dados sĂŁo apresentados e recebidos, garantindo que as interfaces externas se comuniquem efetivamente com a lĂłgica interna da aplicação.
  • Exemplo: Quando um controlador precisa responder a uma requisição com dados de um usuário, o mapper da adapters converte a entidade de domĂ­nio em um DTO apropriado para a resposta da API.
public class UserAdapterMapper {
    public static UserDTO toDTO(User user) {
        return new UserDTO(user.getUsername(), user.getPermissions());
    }
}

Diferença entre Use Cases e Services da Application

Use Cases

  • Definição: Os use cases representam ações ou tarefas especĂ­ficas que os usuários podem executar na aplicação. Cada caso de uso encapsula a lĂłgica necessária para realizar essa ação e possui um ponto de entrada e saĂ­da bem definidos.
  • Responsabilidade: Eles se concentram em um fluxo especĂ­fico e contĂŞm a lĂłgica que orquestra a interação entre diferentes componentes da aplicação, como repositĂłrios e serviços de domĂ­nio.
  • Exemplo: Um caso de uso RegisterUser pode ser responsável por registrar um novo usuário no sistema.
@Component
public class RegisterUser {
    private final UserRepository userRepository;

    public RegisterUser(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void execute(UserDTO userDTO) {
        User user = UserMapper.toEntity(userDTO);
        userRepository.save(user);
    }
}

Services

  • Definição: Os services na camada de application atuam como orquestradores que integram e gerenciam a lĂłgica de aplicação. Eles podem chamar mĂşltiplos casos de uso e tambĂ©m podem incluir lĂłgica adicional que nĂŁo se encaixa em um Ăşnico caso de uso.
  • Responsabilidade: Eles facilitam a reutilização de lĂłgica comum entre diferentes casos de uso e gerenciam o fluxo de dados atravĂ©s de diferentes componentes da aplicação.
  • Exemplo: Um serviço UserService pode gerenciar a lĂłgica de registro e tambĂ©m enviar um e-mail de boas-vindas apĂłs o registro de um usuário.
@Service
public class UserService {
    private final RegisterUser registerUser;
    private final EmailService emailService;

    public UserService(RegisterUser registerUser, EmailService emailService) {
        this.registerUser = registerUser;
        this.emailService = emailService;
    }

    public void register(UserDTO userDTO) {
        registerUser.execute(userDTO);
        emailService.sendWelcomeEmail(userDTO.getEmail());
    }
}

Resumo das Diferenças

  1. Mappers:

    • Application Mappers: Transformam entidades de domĂ­nio em DTOs e vice-versa, focando na comunicação entre lĂłgica de negĂłcios e controladores.
    • Adapters Mappers: Adaptam dados entre a estrutura interna da aplicação e o formato esperado por interfaces externas, como APIs.
  2. Use Cases vs. Services:

    • Use Cases: Representam ações especĂ­ficas que o usuário pode realizar e encapsulam a lĂłgica para essa ação. Eles sĂŁo chamados diretamente pelos controladores.
    • Services: Integram e orquestram a lĂłgica de mĂşltiplos casos de uso e podem incluir lĂłgica adicional. Eles facilitam a reutilização e a coordenação entre diferentes partes da aplicação.

Helper

Gerar chave privada

openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048

Gerar chave pĂşblica a partir da chave privada

openssl rsa -pubout -in private_key.pem -out public_key.pem

About

[WiP] 🚧 Projeto simplificado de um autenticador de usuários utilizando JWT, Spring Boot, Spring Security, JPA, MySQL, SOLID e Clean Architecture.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published