Como funciona o nosso backend
Estruturação
O backend do projeto FwFlex no qual trabalhamos é grande e robusto se compararmos a outros projetos, para conseguir trabalhar nele e deixa-lo organizado, o produto é separado em módulos agrupando funcionalidades relacionadas, de maneira que possamos instalar nos servidores somente o necessário, como por exemplo o pacote básico para funcionamento do produto e um módulo de DHCP. Para o funcionamento dos módulos, existem outras peças fundamentais como o front-end (interface visual do produto) e a camada de infraestrutura do produto, que compreende o provisionamento e empacotamento das funcionalidades.

Para facilitar o entendimento, podemos dividir o nosso backend em 4 (quatro) camadas:
Módulos
Os módulos são o agrupamento de diversos recursos que trabalham em conjunto com funcionalidades relacionadas.
Base
Na base do módulo estão os arquivos que são compartilhados entre os recursos do módulo:
-
Setup: É onde todos os recursos são inicializados/instânciadas (Repo, UseCase, API, Task, Event).
-
Scopes: É onde estão as constantes que definem as permissões do módulo/recursos.
-
Entities: É onde estão todas as entidades do módulo em forma de objeto.
-
Conftest: É onde estão as
fixtures
do pytest usadas nos testes do módulo. Para ler sobre os testes acesse este link. -
Deps: É onde estão alguns métodos utilizados para saber quais ações e recursos possuem auditoria, assim como a lista de escopos do módulo.
-
Models: É onde estão os models, classes que representam os objetos do módulo no banco de dados. Uma representação do banco de dados utilizando Orientação a Objetos.
-
Consts: É onde estão as constantes do módulo utilizadas nos recursos.
Recurso
O recurso se trata de cada funcionlidade de um módulo, ou se fizermos uma analogia ao frontend, representa cada View
.
-
API: Camada de API do recurso, neste camada que as requisições estão.
-
Request: Aqui estão os objetos de requisição, eles herdam dos objetos definidos em Entities. Estes objetos de requisição definem o formato em que os dados são enviados para o Caso de Uso.
-
Use Cases: Escrevemos o caso de uso que une a camada de API, Regra de Negócio e Banco de Dados.
-
Events: Escrevemos os eventos publicados pelo recurso.
-
Tasks: Escrevemos as tarefas que rodam em background e são disparadas pelo recurso.
-
BussinesRules: Aqui é onde escrevemos as regras de negócio do recurso.
-
Repo: Escrevemos toda a camada de comunição e lógica do banco de dados, com algumas abstrações do ORM.
-
Tests: Cada recurso terá pasta uma
tests
, onde escrevemos os testes unitários.
Estrutura em Camadas
Agora que foi explicado cada componente do módulo e recurso, podemos transformar esse entendimento numa explicação do backend em camadas, como é proposto no Clean Arch:
- Camada de Comunição: API, Websocket e Scopes.
- Tratamento de Dados: Request, Entities e UseCases
- Regras de Negócio: BussinesRules
- Comunicação com o Banco de Dados: Repo e Models
- Comunição entre recursos: Events e Tasks

A arquitetura em camadas proposta pelo Clean Arch, como nome diz, estrtura uma aplicação em diversas camadas para diminuir o acoplamento entre elas, isso permite que, caso surja a necessidade de se alterar alguma ferramenta ou até mesmo uma camada ineira, as outras não sejam tão impactadas, em alguns cenarios é possivel que até não sofram nenhuma alteração, separar as obrigações do software é o ponto chave aqui, pois isso torna sua aplicação independente de qualquer ferramenta, não deixando ela presa a eles. Além disso, seu foco é diminuir o retrabalho e código puplicado entre as diversas partes da aplicação.
Para entender melhor sobre Clean Arch e suas boas práticas, clique aqui.
Exemplos
Para tentar facilitar ainda mais o entendimento, aqui está um exemplo de uma estrutura que temos hoje no nosso produto (nossos módulos sofrem uma constante evolução de acordo com novas regras de negócio, sendo assim, há grandes possibilidades de ele não estar mais 100% de acordo com o exemplo mostrado)
Hoje o nosso módulo Cluster, possui apenas um recurso e esta estruturado da seguinte maneira:

Como criar um módulo novo
Adicionar estrutura de pasta do módulo
O primeiro passo é adicionar os seguintes arquivos que fazem parte de um módulo:
server/backend/[módulo]/
server/backend/[módulo]/__init__.py
server/backend/[módulo]/conftest.py
server/backend/[módulo]/consts.py
server/backend/[módulo]/deps.py
server/backend/[módulo]/entities.py
server/backend/[módulo]/models.py
server/backend/[módulo]/scopes.py
server/backend/[módulo]/setup.py
server/backend/[módulo]/[recurso]/__init__.py
server/backend/[módulo]/[recurso]/api.py
server/backend/[módulo]/[recurso]/events.py
server/backend/[módulo]/[recurso]/repo.py
server/backend/[módulo]/[recurso]/requests.py
server/backend/[módulo]/[recurso]/tasks.py
server/backend/[módulo]/[recurso]/use_cases.py
Incluir no produto
Você deve incluir o novo módulo no arquivo server/backend/itflex/config.py
, na constante APPS
.