Esse projeto foi reformulado, agora é o: https://dev.to/gmarcial/core-pay-solucao-5af5
Avisos:
[0] O assunto principal do artigo será a arquitetura do projeto e-Money, onde apenas conterá um resumo sobre o projeto em sí, sendo imprescindível acessar ao repositório do projeto: https://github.com/gmarcial/e-money para conhecer a fundo sobre e não se perder durante a leitura.
[1] Por hora o projeto apenas irá contar com o desenvolvimento e entrega do backend, ficando aberto a possibilidade das demais partes como clientes mobile e web, como contribuição de outros desenvolvedores que venham a ter interesse.
Projeto:
O e-Money é uma solução para um problema fictício, com o objetivo de além a conclusão do meu curso, ser um laboratório de estudos para evolução profissional e portfólio do meu trabalho.
Tem como premissa ser open-source, aberto desde o início, podendo a sua evolução ser acompanhada e ter um aprofundamento sobre em seu repositório no github.
O nome do projeto vem do seu próprio valor monetário, que são créditos eletrônicos com a finalidade servir de moeda dentro da plataforma, onde é transacionada e utilizado para realização de pagamentos.
O e-Money em sua base é um sistema de pagamentos em comum de serviços de entidades que pertencem e participam da plataforma, tendo os usuários como consumidores, que pagam os serviços utilizando a moeda e-Money.
Para um serviço estar disponível para pagamento na plataforma, é preciso se integrar ao hub.
Ex:
Um serviço como o de transporte circular, caso seja participante da plataforma, poderá ser pago com a moeda e-Money.
O desafio
Mesmo este sendo meu primeiro artigo, tenho como objetivo o desafio de registrar o ciclo de desenvolvimento deste projeto, compartilhando não somente as soluções e resultados, mas buscando demonstrar todas as decisões tomadas durante o processo, resultando em um histórico da evolução e portfólio, pois estará aberto a feedback, discussões, compartilhamentos, contribuições e tudo aquilo que venha agregar.
O ciclo é composto pelas seguintes etapas:
Design, develop, test and deploy
Começando pelo design da solução como um todo, que é a proposta deste artigo, ficando os demais registros para respectivas entregas das features, onde ficarei de decidir sua granularidade, podendo vir com um ou mais temas ao mesmo tempo.
Esse artigo tem como objetivo apresentar e explicar a arquitetura inicial projetada, onde provavelmente irá evoluir durante o caminho.
Vamos analisar a arquitetura como um todo e depois passando parte por parte até que percorremos por completo.
Atributos de qualidade
Representam as capacidades necessárias identificadas que a arquitetura precisa ter para poder suportar e atender o produto concebido, tornando uma solução que atende ao negócio.
Para que isso aconteça, essas capacidades serviram de guia da concepção e evolução da arquitetura no seu alto a baixo nível, refletindo diretamente nas implementações e o que se espera das funcionalidades, para que esteja alinhada e continue alinhada como uma solução para o negócio.
O objetivo é deixar expresso e registrado as capacidades identificadas, resumidamente expressar o conceito e uma breve justificativa, que estará aprofundada, expressa detalhadamente no ciclo de desenvolvimento e medidas continuamente.
Base
Capacidades base para contribuir para a vida útil da aplicação, possibilitando ser continuamente funcional, mantida e evoluída, sem estar presa aos criadores, possibilitando também por novos contribuidores e mantenedores.
Readability
Conceito:
O projeto deve ter código de fácil entendimento, podendo ser lido com facilidade por outros engenheiros que venham a contribuir.
Justificativa:
É desejável que o projeto possa seguir em frente, onde outros desenvolvedores possam contribuir.
Com a legibilidade, quem tiver interesse em colaborar de alguma forma, terá uma maior facilidade de entendimento, gastando menos tempo na leitura do código.
Testability
Conceito:
Os diversos níveis da aplicação devem ser possível aplicar diferentes técnicas de teste, conforme o contexto, assegurando os comportamentos esperados e alcançando uma cobertura de segurança através do testes que são os primeiros clientes de nossas implementações.
Justificativa:
É desejável testar a aplicação em diferentes níveis para que possa garantir os comportamentos funcionais, não funcionais e os próprios atributos de qualidade a partir de métricas tiradas dos testes, suportando a qualidade e evolução da aplicação.
Evolvability
Conceito:
Suportar mudanças de forma incremental, sem causar impacto negativo, continuamente atendendo ao negócio suportado e capacidade da aplicação.
Justificativa:
Durante o ciclo de vida da aplicação, ele consequentemente irá mudar, em vez de ser um sofrimento, podemos preparar para que sejam evoluções.
Essas evoluções podem ser funcionalidades novas, novos entendimentos não claros inicialmente, novos problemas, novas capacidades e etc.
O contexto muda e é preciso que a aplicação acompanhe.
Para que essa capacidade seja alcançada, é necessário alcançar outros que estão compostos:
Modifiability:
Ser facilmente modificável, onde é adaptado com facilidade.
Modularity:
É composto de componentes coesos, desacoplados e independentes uns dos outros, onde são compostos, trabalhando juntos para construir o todo.
Simplicity:
Lidar com problemas complexos com soluções simples, buscando sempre a complexidade essencial e não acidental.
Negócio
Capacidades requisitadas para que o negócio possa ser suportado além do produto ser funcional, é preciso que além da entrega da funcionalidade, a aplicação opere essa funcionalidade conforme a demanda e dentro do contexto do negócio.
Auditability
Conceito:
Deve ocorrer a coleta, registro de fatos e evidências das atividades exercidas, com objetivo de captar como, onde, quem e quando foi feito, com objetivo de avaliar a conformidade da operação em relação ao que foi acordado, requisitos legais e etc, senão eficazes e alcançando os objetivos.
Justificativa:
Dependendo do negócio envolvido, o nível de sua criticidade e seus requisitos, como aplicações financeiras, governamentais e outras, recorrentemente ocorrem auditorias para avaliar a conformidade, alguma legislação imposta, podendo a auditoria ser um processo natural, mas também situações críticas de questionamento da veracidade de uma operação.
Atomicity
Conceito:
As operações devem ser atômicas, onde não pode ser considerado ou aceito parte do processo.
Justificativa:
Uma transferência não pode ocorrer pela metade, onde a conta de origem tem o valor subtraído, mas a de destino não recebe o valor ou o contrário.
Isolability
Conceito:
O contexto das operações não devem afetar uma as outras, não as afetando.
Justificativa:
Uma transação não deve influenciar o contexto de uma outra transação, mesmo que ambas tenham envolvido uma entidade em comum, uma deve aguardar a outra, estando sincronizadas.
Consistency
Conceito:
Onde a execução das operações ocorrem de forma válida, seguindo as definições e resultando no que é esperado.
Justificativa:
Uma sequência de operações bancárias devem finalizar com as contas bancárias envolvidas com valores corretos, não tendo mais ou menos dinheiro do que esperado, pois estaria quebrando a consistência do saldo dos clientes.
Durability
Conceito:
Os resultados das operações devem permanecer e perdurar até que outra operação venha a causar alterações.
Justificativa:
A contratação de um serviço ou a realização de um pagamento deve permanecer intacto, não parecendo que não ocorreu, tendo que refazer até efetivar.
Integrity
Conceito:
A aplicação deve ter e tomar medidas da qual mantenha a garantia, manutenção, qualidade e veracidade de suas operações por todo ciclo de vida da aplicação em relação ao seu estado em diversos níveis.
Justificativa:
Aplicações financeiras são muito críticas, suas informações literalmente valem dinheiro, é imprescindível a confiança das movimentações financeiras, mantendo as íntegras, não perdendo ou corrompendo alguma das informações.
Reliability
Conceito:
Manter um nível aceitável de operabilidade, mesmo em situações de falha e anomalias.
Justificativa:
Falhas, situações anormais, erros, ataques e etc, podem e vão ocorrer, mas sem o controle de quando e como, para isso é necessário prevenir, projetando contra essas situações nos vários níveis da aplicação, para que ela continue operando em situações críticas até normalizar.
Diversos níveis e aspectos da aplicação, sendo primária ou terceiras, podem acarretar em uma situação dessa.
Security
Conceito:
A aplicação deve ter medidas da qual se mantenha protegida contra ataques e ações maliciosas que venham explorar e causar danos ao negócio e clientes.
Justificativa:
Aplicações financeiras são muito visadas por criminosos, pelo fato de que podem conseguir ganhos ilícitos ao explorá-las, sendo necessário proteger a aplicação nos diversos níveis e manter uma política e cultura de segurança, conscientizando os envolvidos e até mesmo uma área específica para cuidar da segurança, famosas equipes red e blue.
Availability
Conceito:
Característica de que a aplicação para estar disponível, precisa estar funcionando satisfatoriamente(uptime) nos períodos, com os comportamentos e características especificadas, levando em consideração todo o ciclo da operação.
Quando a aplicação está funcionando e respondendo como esperado o tempo e a quantidade de carga, ela é considerada que tem disponibilidade.
Justificativa:
Aplicações financeiras como uma conta bancária, necessitam estar sempre disponíveis para quando seus clientes necessitam, mas além disso, essas aplicações têm rígidos requisitos como tempo de resposta aceitáveis baixíssimos para uma transação por exemplo, que deve ser alcançado mesmo em picos de carga, pois menos que isso, gastará mais tempo, realizando menos operações em um período, sendo considerada indisponível.
Infraestrutura
Capacidades requisitadas para que a aplicação possa ser suportada, para conforme as necessidades a aplicação operar.
Observabiltity
Conceito:
É poder atraves das informações geradas dos comportamentos do sistema, realizar metricas que reflitam como um historico do seu estado em seus diversos niveis, podendo assim com maior facilidade, entender o que aconteceu, acontece e acontecera.
Justificativa:
Naturalmente sistemas são ou se tornam complexos, dependendo do seu contexto uns são menos ou mais que outros, mas em todos é muito importante que a gente tenha a capacidade de entender o que esta acontecendo com clareza e precisam, seja por exemplo para identificação e resolução de um problema, averigar a assertividade de uma operação e etc, possibilitando sermos mais mais assertivos.
Queremos evitar situações onde não sabemos o que aconteceu, em qual componente ocorreu o problema, seja no banco de dados ou em um serviço terceiro e em qual parte desse componente.
Configurability
Conceito:
O sistema varia os comportamentos que são configuraveis conforme os parametros passados na configuração, não ficando estatico a um unico contexto, podendo alcançar adaptações de forma flexivel, sem muito trabalho.
Justificativa:
Por base os sistemas precisam se adaptar em diferentes contextos, como na implantação em ambientes diversos, que tem diferentes requisitos, mudar um fluxo ou operação a partir de um paretro e etc.
Para que não precisemos fazer alterações a nivel de codigo para adaptar a qualquer uma dessas situações a gente identifica e implementa esses pontos de forma que sejam configuraveis, tendo apenas que alterar os parametros para se adaptar.
Fault Tolerance
Conceito:
Na ocorrencia de falhas, os impactos causados na aplicação devem refletir proprocionalmente a sua gravidade, onde uma falha simples não deve deixar a aplicação inoperavel, mas apenas onerar a parte onde ocorreu a falha.
No caso da indisponibilidade de um sistema upstream, mesmo que as operações dependentes do mesmo não serem operaveis, as demais que não dependem, devem operar normalmente, lidando de uma forma agradevel com a degradação parcial(graceful degradation) ou total.
Justificativa:
Falhas acontecem, apenas na maioria da vezes não sabemos quando, para isso devemos preparar o sistema para lidar com a falha, seja a nivel de design/implementação, infraestrutura e recursos computacionais, acoplamento dos componentes e etc, buscando ter isso como um comportamente natural, ação automatizada e em situações extremas, manualmente com a intervenção humana.
Scalability
Conceito:
A aplicação é projetada para atender o aumento ou diminuição dos recursos computacionais conforme a carga de trabalho, sendo possivel os alterar conforme a necessidade para continuar disponivel e realizando o trabalho, onde a escala pode ser horizontal(scale out) que ocorre com o aumento de nós em um cluster ou vertical(scale up) que ocorre com o aumento de recursos computacionais de unico mesmo nó, como mais memoria ou nucleos.
Justificativa:
Toda aplicação tem uma carga de trabalho base, mas que ele pode variar em momentos esperados como em picos em momentos padrões ou aumentar conforme o negocio cresce.
Cada aplicação tem sua caracteristica, como uma aplicação foodtech tem o aumento em horarios de alimentação e backfriday para e-commerces e marktplaces.
Fora momentos que podem ser inesperados, onde a aplicação deve estar preparada para escalar e aguentar a carga.
Performance
Conceito:
Medida que representa o desempenho da aplicação na realização de suas operações, seja quanto tempo levou, quantos operações foram feitas em um determinado periodo e quantidade de recursos utilizados.
Quão mais rapida realiza as operações, mais operações realiza em um determinado periodo e utilizando menos recursos, mais performatica, tendo uma melhor desempenho.
Justificativa:
Certas operações necessitam de um cuidado especial em relação a performance, por exemplo, pode exigir um tempo de resposta baixo e que sejam realizadas uma quatidade X de operações em um periodo curto de tempo para que esteja disponivel.
Outras podem exigir um melhor uso dos recursos computacionais, otimizando as operações para que use apenas o necessario, diminuindo custos, pois parte dos recursos seriam redistribuidos para as demais operações da aplicação.
Arquitetura:
Amplie a imagem para visualizar melhor
A arquitetura por parte dos clientes, inicialmente é composta somente por primários que farão o interfaceamento com os usuários finais, tendo cada um deles uma finalidade diferente, pois cada contexto tem suas necessidades, sendo web para o back office onde os administradores irão gerenciar a plataforma, já os cidadãos, utilizam as plataformas mobile para acesso e gerenciamento de sua conta e máquinas de pagamento para pagamento dos serviços.
Com objetivo de evitar acesso direto aos recursos, principalmente a api, a frente de todas requisições terá um proxy reverso que pela sua maturidade a escolha foi o nginx. Toda comunicação passará por ele, será o filtro inicial antes do redirecionamento, realizando alguns trabalhos gerais e genéricos em relação a requisição, intermediando entre os recursos internos e os requisitantes.
Uma das partes mais importantes é a api rest utilizando em seus contratos de comunicação o formato json, responsável pela operacionalização da plataforma, aplicando as regras de negócio.
Irá servir aos clientes, estará integrado ao vault para gerenciamento dos segredos que estarão envolvidos na infra e em algumas das regras de negócio, onde iremos nos aprofundar mais a frente em próximos artigos, e o banco de dados postgres para persistências das informações, tanto para a api, quanto ao vault, podendo adotar abordagens relacional e não relacional.
O projeto tem como premissa ser cloud native, que será optado entre a google cloud e a digital ocean, tendo como restrição o custo financeiro final, por se tratar de um projeto sem fins lucrativos e financiado por fundos pessoais.
Todo o projeto por questões de segurança estaria em uma VPC e sub-redes para não estarem expostos diretamente a internet, além de ter o proxy como um gateway, criando um ambiente seguro, gerenciado em várias etapas e claro em containers docker.
Agora vamos falar detalhadamente de cada parte.
Clientes:
Amplie a imagem para visualizar melhor
Todos clientes primários por fim vão representar um usuário final, seja um administrador ou um cidadão.
A responsabilidade do administrador é gerenciar a plataforma, muitas das vezes tendo um terminal de trabalho onde não caberá somente a responsabilidade do gerenciamento da plataforma a e-Money, podendo também trabalhar com outras finalidades, sendo a web uma ótima plataforma para o back office.
Já para os cidadãos que utilizam a plataforma como consumidores finais, que precisam de uma maior praticidade e mobilidade para gerenciarem suas contas de qualquer lugar, a escolha são as plataformas mobile.
Por segurança a plataforma só aceita clientes primários, os quais confiá, sendo autenticados e autorizados para interagir com os serviços, passando pelo processo de MTLS, além do tunelamento seguro para comunicação.
Além da parte do cliente, outro nível de segurança é por parte do usuário final que o utiliza, precisando também se autenticar, para sua identificação durante o ciclo de uso e autorização das ações dentro da plataforma, utilizando tokens de identidade(id token) e acesso(access token).
Quando existir situações sem autenticação do usuário final, MTLS será o suficiente.
Cliente de pagamento:
Amplie a imagem para visualizar melhor
O cliente especifico para pagamentos é por onde as entidades parceiras utilizaram para realizar as transações referente ao pagamento dos serviços consumidos e somente por eles que os mesmos ocorreram.
Além de se autenticar e ocorrer a tunelização da comunicação com MTLS, esse tipo de cliente em especial, irá representar uma entidade da qual efetuará as transações através dele, sua identidade tem que corresponder a da qual foi configurado e certificado.
Somente será autorizado transações quando autenticado e corresponder a entidade para qual foi configurada, logo sua identidade é previamente feita e ligada a sua configuração na plataforma pela administração.
Proxy reverso:
Amplie a imagem para visualizar melhor
O proxy intermedia a comunicação, é quem conhece e redireciona para os responsáveis por lidar com as requisições, podendo aplicar alguma medida manipulando a requisição, segurança, balanceamento e filtro, como só aceitar clientes válidos e confiáveis antes de redirecionar, pois é o primeiro a receber a requisição.
Isolando os recursos do mundo externo, ele é único conhecido e está a frente de toda comunicação, mantendo os demais seguros.
Além de segurança, ele pode contribuir para performance e outras medidas, como cache, filtros e etc. Todos as requisições são intermediadas por ele, podendo fazer a manipulação e ações na entrada e saída, conforme as possibilidades de configuração do nginx.
Outra solução que poderia se encaixar muito bem seria um api gateway, sendo alguns baseados propriamente em cima do nginx.
Contrato com a api:
O consumo da api deve ser claro, tento bem modelado os recursos, expressando seus contratos e principalmente expor o estado, resultado de cada ação e operação, para que diante disso o consumidor possa ficar ciente e a partir disso possivelmente realizar os comportamentos corretos conforme a situação.
Para isso a api deve estar bem documentada, deixando explícito seus recursos, ações, e como realizar e seus comportamentos esperados, além disso um contrato em comum das respostas, seus estados e regras conforme as situações.
Base:
- Status code
- Estado da ação
- Descrição
- Resultado
Ex:
Casos 2xx:
Status code: 201
{
"state": "success",
"description": "A conta foi aberta com sucesso",
"result": {
"resource": "accounts/8129391"
}
}
Casos 4xx:
Status code: 400
{
"state": "Dados invalidos",
"description": "A conta não pode ser aberta, ",
"result": {
"messages": [
{
"property":"...",
"value":"..."
},
{
"property":"...",
"value":[
{
"property":"...",
"value":"..."
},
{
"property":"...",
"value":"..."
},
{
"property":"...",
"value":"..."
}
]
},
{
"property":"...",
"value":"..."
}
]
}
}
Casos 5xx:
Status code: 500
{
"state": "Erro inesperado",
"description": "Ocorreu um erro interno ao tentar processar esta ação"
}
Persistencia dos dados:
Amplie a imagem para visualizar melhor
O RDBMS escolhido será o postgresql, além da sua maturidade, popularidade, eficiência e extensibilidade, aproveitar tanto da sua abordagem relacional, quanto a não relacional com a feature de persistências de arquivos json e jsonb, podendo obter também uma abordagem de documentos.
Toda comunicação com o banco será segura através de conexões utilizando TLS.
Estando em avaliação referente a restrição financeira se será optado por uma abordagem de um serviço gerenciado nas clouds propostas, ou não.
Vault:
Amplie a imagem para visualizar melhor
A aplicação lidará e gerenciará segredos, seja por parte da infraestrutura quanto de algumas regras de negócio, além de armazenar, também gerar.
Não somente os segredos, mas lidar corretamente com criptografia que terá uma grande atuação no projeto.
Para que não precise implementar na mão ou utilizar soluções não tão confiáveis, o vault vem como solução especializada e madura nisso, sendo utilizado como um serviço integrado ao projeto e o melhor, aplicando esses conceitos críticos de forma correta, além de abrir outras possibilidades, pois o mesmo tem mais features do que está descrito aqui e de uma forma mais aprofundada.
A persistência das informações ocorrerá a partir da utilização de um banco postgres próprio e isolado.
Considerações finais
Agradeço por todos que leram até o final, é um passo importante para mim estar escrevendo meu primeiro artigo e estar compartilhando minha experiência nesse projeto.
Provavelmente nos próximos capítulos já será sobre a primeira entrega, dando início ao desenvolvimento.
Novamente, estou aberto a feedbacks, discussões, trocar uma ideia, compartilhar, contribuições e tudo aquilo que venha agregar e contribuir para a evolução contínua.
Obrigado.
Top comments (0)