Arquitetura Hexagonal: Minha primeira aplicação Clojure

Marina Cavalari
5 min readJun 23, 2021

--

Olá pessoal, meu nome é Marina Cavalari, e eu sou administradora. Aos poucos, fui migrando de carreira, e gostaria de compartilhar como foi essa transição e, quem sabe, servir de inspiração para quem busca fazer uma mudança para a área de tecnologia e se interessa por Programação Funcional. Comecei no mundo de dados e sistemas trabalhando com Python, mas foi através de algumas aulas de Java (nunca vou esquecer dos exemplos que me ensinaram classes, tipagem e metodo construtor `“Moto moto = new Moto()”`) que realmente comecei a aprender programação, lógica, tipos de linguagens e etc.

Dado esse contexto, hoje estou direcionando minha carreira para criar aplicações back-end, e enfim me tornar Engenheira de Software, usando Clojure como minha principal linguagem (Difícil demais ter que escolher entre Clojure e Scala, então eu finjo que escolhi, mas não rs).

Doctor Who

Pra começar vamos ter que ter algumas coisas instaladas no nosso computador, tanto para conseguirmos rodar o Clojure em si, como para facilitar a nossa vida:

Outros editores tem ferramentas que dão o mesmo resultado, no frigir dos ovos, todas usam as mesmas fontes para identar, colorir, e agilizar o nosso processo de desenvolvimento.

O código está disponivel neste repo, e por aqui vou explicar as camadas e como cada uma delas trabalha e pode ser isolada, testada e deployada sem grandes interferências ao resto do código. Minha aplicação está segregada entre lógica, banco de dados e controladores (também conhecidos como orquestradores).

A parte do db é responsável apenas por armazenar o seu banco de dados, no meu caso, um atom, (banco em memória nativo do Clojure) e também as funções de acesso ao banco, ou seja, todas aquelas onde podemos encontrar determinado registro dado um identificador, funções de inserção, ou para deletar registros. Uma vez as funções de db isoladas em seu próprio arquivo .clj, nós podemos adicionar ou remover mais funções sem “vazar” essas atribuições para outras camadas.

A lógica (Logic) é responsável por manter toda a regra de negócio da nossa aplicação, e é importante que essas funções sejam puras, para que nunca seja alterado o estado do input, mas devolvam coisas novas, para que a nossa aplicação saiba como seguir depois. Por exemplo, quando queremos adicionar um determinado produto no nosso carrinho no aplicativo de entregas, a lógica é, não podemos adicionar dois produtos iguais em um intervalo menor de dois minutos, dessa forma, sempre teremos funções que validarão essa regra e retornará se determinada ação é válida ou não.

Aqui é onde toda a mágica acontece: Controladores (Controllers). Os controladores são responsáveis por unificar as funções de lógica e de db nessa aplicação (em outros casos, também podemos ter adaptadores, que podem estar presentes nos controladores). A principal função do controlador é rotear as tarefas para as respectivas camadas de processamento. Então, ao fazermos uma requisição para nossa aplicação, enviando dados como entrada(no exemplo, o input é feito através do stdin), nosso controlador é o principal agente na execução das chamadas das funções pertinentes. O controlador também é a camada responsável por expor possíveis irregularidades ou violações, fazendo assim o tratamento de erros dos nossos inputs e outputs.

Uma vez que temos uma breve explicação de todas as camadas, podemos olhar um exemplo simples de código:

criação de um carrinho

O controlador é responsável por centralizar todas as funções que usaremos para criar um carrinho, dessa forma, o input chegará e será encaminhado para uma função de assertividade, para garantir que ainda não há (ou se houver, enviar um erro) um carrinho criado. Uma vez que essa função retorno que não há carrinhos criado, podemos seguir para a inserção no banco e depois usar esse registro em uma das muitas outras funções que nossa aplicação tem.

Doctor Who

Testes

Eles merecem uma parte, um capítulo, e uma biblioteca inteira sobre eles, e muitas vezes, são ignorados como se fossem um patinho feio que ainda não teve a oportunidade de se transformar em cisne. Muitas empresas, grandes, pequenas, carecas, cabeludas, de tecnologia ou não, ainda ignoram os testes, que são as melhores formas de evitar bugs em produção. O desenvolvimento de testes pode ser feito enquanto criamos o código, podem ser definidos antes de criarmos a nossa aplicação, apenas respeitando as lógicas de negócios previamente desenhadas, e etc. Mas, ainda consomem um tempo do desenvolvedor, e isso em muitos casos é visto como não essencial. Clojure é simples e elegante, com poucas linhas de código somos capazes de fazer muitas coisas, e essa vantagem se estende também para o desenvolvimento de testes.

O mais interessante na testagem das funções é a praticidade em isolar as funções e testar elas ao seu limite dos corner-cases e evitar possíveis comportamentos inesperados, dessa forma, conseguimos criar arquivos de testes para lógica, adaptadores, db, além de testes de integração. Avaliar as funções de forma unitária, garante que estamos entregando e recebendo exatamente o que a necessidade do negócio precisa, e testes de integração garantem que a nossa aplicação conversa muito bem entre si, evitando que as funções mandem dados ou estruturas erradas entre si.

Doctor Who

Links adicionais

Meu relato é breve e bem simplista, mas busca mostrar que é possível ser simples, e ainda assim, ser escalável, uma vez que essa forma de arquitetura, nos permite crescer e integrar com inúmeros micro-serviços em uma estrutura parecida, sendo essa uma das maiores vantagens de se ter o código modularizado. A lista abaixo contém exemplos de aplicações web que também são feitas nessa estrutura de arquitetura, e um repo interessante do Nubank, mostrando um exemplo básico de micro-serviço que eles usam:

Acredito que com a divulgação de mais informações entre a comunidade, podemos ir cada vez mais longe e entregar melhores resultados, mesmo que comecemos com contribuições pequenas! Então caso haja dúvidas, sugestões, avisos ou correções, não perca tempo, me chame para um bate papo sobre clojure, programação, ou dicas de adm também :)

Github

Instagram

Doctor Who

--

--