PoC: Evoluindo o Busca Cep com DDD e clean code
Published: 2023-09-01 16:13:53

Este post é uma continuação do post anterior. Dessa vez eu vou falar sobre as melhorias que eu fiz no código e na evolução do script do Busca Cep que agora virou até mesmo uma Prova de Conceito - PoC.

Pesquisando na internet sobre a definição de prova de conceito, eu encontrei isso aqui:

_Uma prova de conceito (PoC) é uma demonstração prática da viabilidade de uma ideia ou método. É uma implementação resumida, simples e incompleta, que antecede o protótipo do projeto._

Dessa vez eu apliquei um pouco de domain-driven design, clean code, testes e fiz até mesmo um front-end vergonhoso e cheio de Javascript e CSS feitos de forma bem artesanal e _o que você vai ler abaixo é a minha implementação resumida, simples e incompleta do Busca Cep._

Aqui está o [link para o repositório do projeto no GitHub](https://github.com/marcelomatz/buscaCep).

**Criando um Serviço de Busca de CEP Simples com Go**

O Busca Cep nasceu junto com [este artigo](https://dev.to/marcelomatz/criando-um-servico-de-busca-de-cep-simples-com-go-1ocj) que fala do meu aprendizado em cima da linguagem de programação Go. 

Eu demonstrei como fazer uma implementação usando _Go_ extremamente simples para consultar, consumir e tratar as informações recebidas a partir de uma requisição http para o web service da [ViaCep](https://viacep.com.br/).

## Busca Cep PoC

Como **o meu objetivo** é estudar sobre desenvolvimento de software, eu implementei algumas melhorias em cima do exemplo do Busca Cep (criado no artigo anterior) e aproveitei essa implementação para colocar em prática alguns conceitos que são fundamentais no dia a dia de um dev.

### Vamos falar de commit
O [primeiro commit](https://github.com/marcelomatz/buscaCep/commit/bddc55196b416316f8c1ad867d2677b480632d79) que eu fiz foi implementando um tratamento de erros, ainda na função Main.

Na real, na real, foi nesse momento que eu pensei em transformar tudo isso em uma prova de conceito e assim começou a pequena jornada de mudanças.

Mais adiante ainda eu viria a começar a separar o software de acordo com as responsabilidades de cada coisa, mas neste momento eu lembro de estar focado lendo sobre erros no Go.

![Image Improve error handling & reporting in Main.go](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fn4mnfynh5gqyt8w16ic.png)

O mais interessante de tudo, na minha opinião, é que muitas vezes por causa de uma simples mudança no código, a maneira como nós pensamos muda completamente.

Meio que faz sentido aquilo que o _mano Alberto falou: "A mente que se abre a uma nova ideia jamais voltará ao seu tamanho original"_

### Aprendizados

O meu maior aprendizado com essa PoC foi perceber que as alterações mais sutis, foram as que mais me fizeram pensar e consequentemente isso me fez escrever menos código.

Como diz o filósofo:
> Pensar melhor e executar melhor é melhor do que pensar pior e executar pior.

As startups gostam de adotar o discurso de: _erre rápido, corrija rápido!_
_A moral é que até hoje eles estão errando rápido e levando semanas para corrigir_ 😂

Sobre o commit do tratamento de erros:
`incluí um novo método isEmpty na struct ViaCep para verificar se todas as suas propriedades estão vazias. Isso ajuda a lidar com situações em que a pesquisa CEP não retorna nenhum resultado. Consequentemente, uma resposta de erro com a mensagem "CEP não encontrado" é retornada quando um resultado de pesquisa CEP está vazio. Essa alteração aprimora o tratamento de erros e leva a um status de resposta HTTP mais preciso.`

---

### DDD - Primeiros passos com Domain-Driven Design.

**Domain-Driven Design (DDD)** é uma abordagem de design de software que coloca o domínio do problema no centro do processo de desenvolvimento.

Desde que eu comecei a ler o livro do Eric Evans sobre DDD, além de me sentir um pouco mais burro, eu fui entendendo como e quando faz sentido criar essa separação em camadas.

E justamente por eu entender isso é que eu sei que uma PoC como o Busca Cep não tem a necessidade de se trabalhar um design de software mais avançado. Tanto é verdade que a primeira versão não passava de um simples script na Main.

Eu ignorei este fato de ser um projeto pequeno e defini que a ViaCep é o meu domínio principal. O meu código todo gira em torno de fazer uma requisição http no ViaCep.

A partir disso eu parti para organizar o meu projeto de forma que essa organização reflita essa separação entre as minhas regras de negócio e o domínio principal.

O [commit](https://github.com/marcelomatz/buscaCep/commit/78a2fc92aaf607a7a3e5755499c509c1c2cb51a4) chama-se: **Refactoring ViaCep data lookup to improve modularity**
 
`Este commit reorganiza o código BuscaCep em pacotes diferentes. O principal objetivo era melhorar a modularidade do código, separando responsabilidades e tornando o código mais fácil de testar.`

`A estrutura ViaCep e a função BuscaCep foram movidas de main.go para um novo arquivo, domain/viacep.go. Este arquivo agora encapsula funcionalidades relacionadas à busca e verificação de dados do ViaCep.`

`Da mesma forma, a função BuscaCepHandle foi movida para um novo arquivo, handlers/cep.go. Este arquivo agora trata do fluxo de solicitação/resposta HTTP para pesquisas CEP (Código Postal).`

`Dois novos arquivos de teste domain/viacep_test.go e handlers/cep_test.go também foram criados, estabelecendo as bases para futuros casos de teste.`

O que eu fiz de mudança no Busca Cep neste momento foi separar o projeto de forma física e lógica. Eu criei um diretório chamado `domain` e outro chamado `handlers` e separei os arquivos Go correspondentes dentro de cada diretório.

Em **domain** eu separei justamente o que está relacionado ao domínio do meu negócio, que neste caso é o web service do ViaCep onde eu faço a requisição http. Em **handlers** eu deixei as funções que tratam de requests, parâmetros, etc.

Por mais que existam formas mais elegantes de se fazer essa separação, pra mim o aprendizado que eu tive por simplesmente ter parado um tempo para pensar nessa separação foi sensacional.

Sem falar que isso tornou o meu código muito mais fácil de ser testado. Eu consigo pensar o que eu quero testar e consigo separar isso de uma forma mais organizada.

### Testes

Enquanto eu avançava na implementação das melhorias, eu queria ter uma experiência trabalhando com testes em Go.

Tanto para erros, quanto para testes, o Go oferece um suporte built-in maravilhoso. Quem já passou raiva com outros linguagens de programação por causa de captura de erros, sabe o luxo que é ter uma lang que realmente se preocupa com isso.

Eu ainda vou estudar mais sobre testes e certamente vou escrever mais sobre este assunto. Por enquanto eu estou satisfeito com o que eu aprendi sobre testes em Go.

### Refatorando
Refatorar código é uma delícia. Sério! Eu sou do pensamento que todo dev deveria amar o processo de refatorar código.

Parece que as coisas se tornam mais simples e ao mesmo tempo mais divertidas de serem feitas quando a gente refatora.

Eu comecei a refatorar o projeto, criar as separações e ver que eu podia ir mais longe, resolvi simular um front-end.

Criei uma tela que permite ao usuário fazer o input de um cep e ver as informações sobre ele.

![Image print do frontend](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8m9qfielfoie6bscbqex.png)

O mais legal é que, para testar isso dentro dessa aplicação e não precisar subir o backend de um lado e o front de outro, eu fiz com que a rota principal ("/") retornasse um arquivo html, enquanto a outra rota faz a requisição para o web service.

No fim das contas, no frontend eu fiz um tratamento usando Javascript para exibir as informações na tela, mas por baixo dos panos o backend em Go é quem faz todo o processo.

Mais para frente, quem sabe, eu não faça um frontend (true) que consome o microsserviço do Busca Cep.

Por enquanto eu to feliz com o que foi feito até aqui com algo que começou super simples e foi ganhando corpo e servindo ao seu propósito de ser algo de valor acadêmico.

Considere deixar um comentário se você tem alguma dúvida, crítica ou sugestão.

Até a próxima!