A Arquitetura Hexagonal, também conhecida como Ports and Adapters, é um modelo arquitetural criado por Alistair Cockburn para tornar aplicações mais modulares, flexíveis e testáveis. Essa abordagem separa a lógica de negócio das dependências externas, como bancos de dados, APIs e interfaces gráficas, garantindo um sistema desacoplado e de fácil manutenção.
🔄 O Conceito da Arquitetura Hexagonal
A ideia principal da Arquitetura Hexagonal é criar um núcleo independente que contenha as regras de negócio da aplicação, se comunicando com o mundo externo através de ports (portas) e adapters (adaptadores). Isso permite que diferentes tecnologias possam ser conectadas sem impactar diretamente no core da aplicação.
A representação visual da arquitetura é um hexágono, mas essa forma é apenas uma ilustração do conceito de múltiplas entradas e saídas.
Estrutura da Arquitetura Hexagonal
- Core (Núcleo da Aplicação): Contém as regras de negócio e não deve depender de frameworks ou tecnologias específicas.
- Ports (Portas): Interfaces que definem os pontos de interação da aplicação com o mundo externo.
- Adapters (Adaptadores): Implementações concretas das portas, conectando a aplicação a bancos de dados, APIs externas, interfaces de usuário, entre outros.
Essa separação permite que mudanças no banco de dados, por exemplo, sejam feitas sem impactar o core da aplicação.
🛠️ Implementando uma Arquitetura Hexagonal em TypeScript
Vamos construir um sistema de cadastro de usuários seguindo a Arquitetura Hexagonal.
1. Criando a Port (Interface)
Começamos definindo uma interface que representa um repositório de usuários:
interface UserRepository {
create(user: User): Promise<User>;
findByEmail(email: string): Promise<User | null>;
}
Essa interface define o contrato que qualquer repositório de usuários deve seguir, independentemente da tecnologia utilizada.
2. Criando o Core (Serviço de Negócio)
Agora, criamos um serviço que usa a interface UserRepository
para gerenciar usuários:
class UserService {
constructor(private userRepository: UserRepository) {}
async registerUser(email: string, name: string) {
const existingUser = await this.userRepository.findByEmail(email);
if (existingUser) throw new Error('User already exists');
const newUser = { email, name };
return this.userRepository.create(newUser);
}
}
Aqui, o UserService
não sabe se os dados serão armazenados em um banco relacional, NoSQL ou mesmo em um arquivo. Ele apenas interage com UserRepository
.
3. Criando um Adapter (Implementação do Repositório para MongoDB)
Criamos um adaptador para o MongoDB, implementando a interface UserRepository
:
class MongoUserRepository implements UserRepository {
async create(user: User): Promise<User> {
return await MongoDB.collection('users').insertOne(user);
}
async findByEmail(email: string): Promise<User | null> {
return await MongoDB.collection('users').findOne({ email });
}
}
Essa implementação pode ser substituída por outra (como um banco SQL) sem alterar o UserService
.
4. Conectando Tudo na Aplicação
Criamos uma API Express para interagir com o UserService
:
const userRepository = new MongoUserRepository();
const userService = new UserService(userRepository);
app.post('/register', async (req, res) => {
try {
const user = await userService.registerUser(req.body.email, req.body.name);
res.status(201).json(user);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
Agora, nossa aplicação segue a Arquitetura Hexagonal, permitindo trocar de banco de dados facilmente, sem alterar a lógica de negócio.
✨ Benefícios da Arquitetura Hexagonal
🔄 Baixo acoplamento: O core da aplicação não depende de tecnologias específicas.
🔧 Fácil manutenção: Permite trocar partes da aplicação (como o banco de dados) sem alterar o core.
🔍 Maior testabilidade: Podemos testar a lógica de negócio isoladamente, substituindo adaptadores por mocks.
🚀 Flexibilidade: A mesma lógica de negócio pode ser utilizada em diferentes interfaces (API REST, CLI, UI, etc.).
💪 Conclusão
A Arquitetura Hexagonal é uma excelente abordagem para tornar aplicações mais modulares, organizadas e testáveis. Ela facilita a evolução do software, permitindo a troca de componentes sem impactar a lógica de negócio.
Se você trabalha com aplicações escaláveis e deseja evitar o alto acoplamento, considerar a Arquitetura Hexagonal pode ser um excelente caminho!
O que achou desse modelo arquitetural? Pretende utilizá-lo nos seus projetos? Deixe seu comentário! 🚀
Top comments (0)