Skip to content

jtonynet/go-products-api

Repository files navigation

Go Products API Challenge

Gopher azul, simbolo da linguagem Golang empurrando um carrinho de compras com caixas de produtos

Postman Logo go Echo Framework MySQL Logo Docker Logo Ubunto Viper DotEnv Logo GitHub Logo MermaidJS Logo VsCode Logo Swagger Logo GithubActions Logo Prometheus Logo Grafana Logo

Badge Status Github Project Badge GitHubActions

*Status ENCERRADO - Primeiro commit dia: 07/02/2024 Ultimo commit dia 12/02/2024 - 5 dias corridos


🕸️ Encontre-me na web

linkedin dev.to gmail Twitter instagram


📁 O Projeto

⤴️ index

Go Products API

  1. ⤴️ Índice
  2. 📗 Sobre
  3. 💻 Rodando o Projeto
  4. 📰 Documentação da API
  5. 📊 Diagramas
  6. Testes
  7. 🪲 Debug
  8. 🕵️ Observabilidade
  9. 👏 Boas Práticas
  10. 🧠 ADR - Architecture Decision Records
  11. 🔢 Versões
  12. 🧰 Ferramentas
  13. 🤖 Uso de AI
  14. 🏁 Conclusão

⤴️ de volta ao índice


📗 Sobre

Este repositório foi criado com a intenção de propor uma possível solução para o seguinte desafio:

👨‍💻 Case Dev Backend:

Vamos construir uma API? A API a ser desenvolvida deve conter rotas C.R.U.D. de produtos, seguindo um bom design de API.

  • Requisitos:
    • Rota para criação de produtos.
    • Rota para consulta de produtos.
    • Rota para atualização de produtos.
    • Rota para exclusão de produtos.

Sinta-se livre para aprimorar a API e demonstrar seus conhecimentos.

  • Stack Back-end

    • Postman
    • GoLang
    • Echo Framework
    • MySQL
  • Padrões de qualidade.

    • API Design
    • Código Limpo (Clean Code)
    • Padrões e convenções GoLang

Dada sua simplicidade, uma vez que se trata de um CRUD simples. Faz sentido utilizar Arquitetura de Duas Camadas o que aumenta o ritmo do desenvolvimento porém mantendo a qualidade do resultado final. Construido junto a uma visualização estilo Kanbam no Github Project

Foco em garantir estabilidade com TDD e uma implementação minima de CI no GitHub Actions, boas práticas de design de código e Observabilidade com Prometheus e Grafana garantindo a robustez necessária e devidos aprimoramentos

Exatamente por parecer ser "simples", é necessário ter um bom nível de qualidade.

O desenvolvimento e os testes foram executados no sistema Linux Ubuntu 20.04.6 LTS e testada em Linux Ubuntu 22.04.3 LTS.


⤴️ de volta ao índice


💻 Rodando o Projeto

Crie uma cópia do arquivo sample.env com o nome .env e rode o comando docker compose (de acordo com sua versão do docker compose) no diretorio raiz do projeto:

$ docker compose build
$ docker compose up

Swagger Postman collection

Dentro da pasta ./scripts/postman-collection/go-products-api.postman_collection.json encontra-se o arquivo JSON básico que pode ser importado no seu Postman para auxiliar em testes manuais e desenvolvimento.

⤴️ de volta ao índice


📰 Documentação da API

Com a aplicação em execução, a rota de documentação Swagger fica disponível em http://localhost:8080/swagger/index.html#/ .

Acesse-a para realizar validações, caso prefira ao usar o Postman. Utilizar o Swagger-API também é uma boa maneira de tornar a aplicação aderente às boas práticas e ao design de API.

O cliente deve informar o UUID do recurso, seguindo as modernas práticas de desenvolvimento. Para validações, você pode utilizar um site gerador de UUIDs. Outras restrições e características dos recursos que podem ser criados, obtidos, listados e deletados podem ser visualizadas na seção 'Models' do Swagger.

Swagger Swagger docs


Gerando a Documentação:

Para gerar a documentação, você precisa ter o Golang, o Swaggo e o projeto instalados localmente e executar o seguinte comando no diretório raiz do projeto:

swag init --generalInfo cmd/api/main.go -o ./api

✍️ Nota:

Existe um bug na geração da documentação do Echo Swagger. No arquivo ./api/docs.go está gerando duas propriedades na struct swag.Spec que não são reconhecidas. A solução encontrada no momento é remover manualmente essas propriedades a cada geração da documentação.

  LeftDelim:        "{{",
  RightDelim:       "}}",

*A geração da documentação necessita de mais testes no S.O. Windows


⤴️ de volta ao índice


📊 Diagramas do Sistema

graph LR
    subgraph User Flow
      ADMIN(["👤 User"])

      ADMIN --> CREATE_PRODUCT("💻 Create Product")
      ADMIN --> RETRIEVE_PRODUCT_LIST("💻 Retrieve Product List")
      ADMIN --> RETRIEVE_PRODUCT("💻 Retrieve Product")
      ADMIN --> UPDATE_PRODUCT("💻 Update Product")
      ADMIN --> REMOVE_PRODUCT("💻 Remove Product")
    end

    subgraph go-products-api - Two Tier Architecture -
      subgraph Handlers
        API_CREATE_PRODUCT("🖥️ Create Product")
        API_GET_PRODUCTS("🖥️ Get Products")
        API_GET_PRODUCT("🖥️ Get Product by UUID")
        API_UPDATE_PRODUCT("🖥️ Update Product by UUID")
        API_DELETE_PRODUCT_BY_ID("🖥️ Delete Product by UUID")
      end


      subgraph Entities
        ENTITY_PRODUCT("📄 Product")
      end

      subgraph DATABASE
        CATALOGO_DB[("🗄️ MySQL <br/> catalogo-db")]
      end 
    end
  

  CREATE_PRODUCT -->|http POST| API_CREATE_PRODUCT
  RETRIEVE_PRODUCT_LIST -->|http GET| API_GET_PRODUCTS
  RETRIEVE_PRODUCT -->|http GET| API_GET_PRODUCT
  UPDATE_PRODUCT -->|http PATCH| API_UPDATE_PRODUCT
  REMOVE_PRODUCT -->|http DELETE| API_DELETE_PRODUCT_BY_ID


  API_CREATE_PRODUCT-->ENTITY_PRODUCT
  API_GET_PRODUCTS-->ENTITY_PRODUCT
  API_GET_PRODUCT-->ENTITY_PRODUCT
  API_UPDATE_PRODUCT-->ENTITY_PRODUCT 
  API_DELETE_PRODUCT_BY_ID-->ENTITY_PRODUCT




  ENTITY_PRODUCT-->CATALOGO_DB

*Diagrama geral com baixo nível de fidelidade


⤴️ de volta ao índice


✅ Testes

Para testar localmente, é necessário ter o Go v1.21.1 instalado. Execute os para garantir o funcionamento correto da API e do banco de dados. Inicie o banco de dados na raiz do projeto usando docker-compose.

docker compose up mysql-go-products-api

Em outro terminal mas ainda na raiz do projeto, execute o comando:

go test -v ./ ./internal/handlers/

obtendo uma saida similar a seguinte:


Os testes também são executados como parte da rotina minima de CI do GitHub Actions, garantindo que versões estáveis sejam mescladas na branch principal. O badge TESTS_CI no cabeçalho do arquivo readme é uma ajuda visual para verificar rapidamente a integridade do desenvolvimento.

⤴️ de volta ao índice


🪲 Debug

Utilizando o VSCode como editor de código (maiores informações aqui) com a seguinte configuração no arquivo .vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch go-products-api",
            "type": "go",
            "request": "launch",
            "mode": "debug",
            "program": "${workspaceFolder}/cmd/api/main.go",
            "cwd": "${workspaceFolder}",
            "trace": "verbose",
        },
        {
            "name": "Test Smoke Happy Path",
            "type": "go",
            "request": "launch",
            "mode": "test",
            "program":"${workspaceFolder}/main_smoke_test.go",
            "trace": "verbose",
        },
        {
            "name": "Test Integration Corner Cases",
            "type": "go",
            "request": "launch",
            "mode": "test",
            "program":"${workspaceFolder}/internal/handlers/productHandler_integration_test.go",
            "trace": "verbose",
        }
    ]
}

Altere a connection com a database para localhost em seu arquivo .env

DATABASE_HOST=localhost  # mysql-go-products-api | localhost - To run localy (without all docker compose dependency) or debug use localhost

E suba o Banco de Dados antes de iniciar seu debug:

docker compose up mysql-go-products-api
Uma seção de Depuração de Testes da aplicação pode ser vista aqui:

⤴️ de volta ao índice


🕵️ Observabilidade

Prometheus:

Apos rodar com sucesso o docker compose up como visto anteriormente, acesse:


Configurando o Grafana:

A primeira vez que executarmos o Grafana, entramos com usuário/senha padrão de admin/admin. Ele solicita a alteração da senha, para facilitar o desenvolvimento local, alteramos para admin/12345.

Uma vez dentro do Grafana em sua primeira execução, também precisamos criar uma conexão Datasource com o Prometheus (que acessamos acima). Procure por `Connections > Add New Connection` digite Prometheus no campo de Search, selecione-o, clique em `Add New Datasource` e configure-o com a URL: http://prometheus-go-products-api:9090 e clique no botão Save & test no final da página

Agora você pode usar o menu `Dashboards > New > Import` para importar o arquivo dash-go-products-api.json que está localizado no diretório: ./scripts/grafana-dashboards. Acesse o diretório em seu computador, clique e arraste o arquivo para o campo correto especificado pela tela Upload Dashboard JSON File

Vincule o Dashboard a conexão previamente criada e acesse-o

Quando adequadamente importado, o Dashboard estará disponível e responderá às solicitações que você pode simular pelo Postman ou Swagger.

A partir dessas métricas dos dashboards, temos uma ideia da saúde da API e quais são as reais necessidades de escala que ela deve ter em produção, o que nos dá uma ideia de quais arquiteturas e abordagens poderão ser utilizadas para atender às suas demandas, incluindo testes de carga, possíveis caches defensivos, filas, etc.

Nossas decisões de Arquitetura e Design de Sistemas devem sempre ser baseadas em dados!


⤴️ de volta ao índice


👏 Boas Práticas


⤴️ de volta ao índice


🧠 ADR - Architecture Decision Records


⤴️ de volta ao índice


🔢 Versões

As tags de versões estão sendo criadas manualmente a medida que o projeto avança com melhorias notáveis. Cada funcionalidade é desenvolvida em uma branch a parte (Branch Based, feature branch) quando finalizadas é gerada tag e mergeadas em master.

Para obter mais informações, consulte o Histórico de Versões.


⤴️ de volta ao índice


🧰 Ferramentas


⤴️ de volta ao índice


🤖 Uso de AI

A imagem do cabeçalho desta página foi criada com o auxílio de inteligência artificial e um mínimo de retoque e construção no Gimp Gimp Logo

Foi utilizado os seguinte prompt para sua criação no Bing IA:

Gopher com carrinho de compras "gopher azul, simbolo da linguagem golang, empurrando um carinho de compras com caixas escrito REST, API, ECHO e Swagger dentro desse carrinho, estilo cartoon, historia em quadrinhos, fundo branco chapado para facilitar remoção"(sic)

IA também é utilizada em minhas pesquisas e estudos como ferramenta de apoio; no entanto, artes e desenvolvimento são, sobretudo, atividades criativas humanas.

Contrate artistas para projetos comerciais ou mais elaborados e Aprenda Engenhosidade!


⤴️ de volta ao índice


🏁 Conclusão

Conduzi o desafio no espírito do TDD e das melhores práticas que conheço. Preocupando-me com a coleta de métricas visando expansão futura, caso os dados apontem essa necessidade, e utilização de ferramentas que fazem parte do parque de tecnologias do proponente do desafio. Mantive-me focado nos prazos das tarefas e na qualidade do código desenvolvido.

Aqui deixo alguns pontos que imagino serem melhorias possíveis (alguns merecem seus próprios ADRs):

  • Bug do Swagger, cuja solução manual que adotei impediu a geração da documentação automaticamente a cada subida da aplicação.
  • Melhoria no script do Postman para melhor compartilhamento entre equipes.
  • Montagem do docker-compose que poderia incluir automaticamente o Dashboard Grafana.
  • Melhorias no Log e utilização de algum centralizador de Logs como Grafana Loki ou Logstash
  • Utilização de algum APM
  • Processo de CD
  • Testes de Performance e Carga que poderiam rodar em conjunto com nossa monitoria local. Gostaria de ter utilizado o Gatling com essa finalidade.
  • A partir de tais testes, poderíamos decidir escalar:
    • Implementação de um cache defensivo com Redis para consultas.
    • Criação de produtos em fila RabbitMQ ou outro, com workers, permitindo o aumento de requisições na rota POST, se necessário.

Algumas das melhorias citadas (Gatling, Cache Defensivo e Filas) desenvolvi como POC em outro projeto que não está na solução "ótima", mas servem para nortear possibilidades.

Terei prazer em discutir sobre o assunto e sinta-se à vontade para visitar outros dos meus repositórios.

😊🚀


⤴️ de volta ao índice

About

🔐 ENCERRADO - Possível solução para o desafio de API de Produtos

Resources

Stars

Watchers

Forks

Packages

No packages published