Dev com négocios

Marcos Henrique

Dev com negócios

image.png

Integração Entre Sistemas: Desafios e o Valor do Planejamento a Longo Prazo

Provavelmente você já viu algum sistema ou site com uma funcionalidade de integrar a outro provedor. Um exemplo que vi nos últimos dias é o do Strava, um aplicativo de monitoramento de corrida, ciclismo, etc. Nele, existe a opção de conectar com o Spotify, permitindo gerenciar as músicas mais facilmente pelo próprio aplicativo.

De fato, existem vários tipos de integração. Existem aquelas em que você manipula informações por meio de endpoints, aquelas onde a aplicação é notificada por um webhook (evento) e até mesmo a conexão direta com o banco de dados (não recomendaria esse formato), sendo o webhook talvez o padrão mais adequado e utilizado atualmente.

Mas desenvolver uma integração como essa não é uma das tarefas mais fáceis. Neste artigo, vou explorar não apenas os erros que cometi ao longo do caminho, mas também as lições valiosas que aprendi, que podem ajudar outros desenvolvedores a evitar armadilhas semelhantes e a construir sistemas mais robustos e eficientes.


Partindo do Começo

COSTPAT

COSTPAT

A essa altura do campeonato, se você já me acompanha por aqui, provavelmente já conhece o COSTPAT. Mas, para os novatos, vou apresentar brevemente. Aos 15-16 anos, recebi a oportunidade de desenvolver um sistema de gestão patrimonial. Esse projeto veio em um momento em que eu estava quase desistindo de programação e empreendedorismo, depois de vários projetos incompletos. Decidi me dar uma segunda chance e, com isso, dediquei as minhas férias da escola para o que seria a primeira versão do COSTPAT. E bom, deu certo! Não somente voltei a ter vontade de desenvolver, como passei por diversas situações que, provavelmente, seriam assumidas por um sênior 😅. Isso me ensinou a lidar melhor com os erros e a tirar da minha cabeça que eu era incapaz de fazer o que precisava ser feito!

Voltando para o tema deste post, após o sucesso do COSTPAT, passando por diversos municípios de Sergipe e após um longo processo de licitação, chegamos à Prefeitura Municipal de Aracaju. Esse contrato me fez passar por questões que nunca havia enfrentado antes, como a migração de mais de 300.000 bens em CSV, aplicando validações com Python até a integração com o sistema ERP da prefeitura.

pedrope.gif

E é nesse ponto que começaram os problemas, o primeiro deles:

1 - Infraestrutura

Na época, me pareceu a solução mais eficiente ter servidores dedicados somente a esse contrato, já que era o maior cliente até então. Na minha cabeça, fazia sentido separar tudo, incluindo o CÓDIGO.

Então, assim foi feito: criei bancos de dados, droplets (como são chamados os servidores na Digital Ocean) e novos repositórios, clonando o que já existia no projeto ‘original’.

2 - Modelagem do Banco

Como já tínhamos separado o banco de dados para essa aplicação e o tempo estava curto, pensei: por que não adaptar a nossa modelagem do banco ao serviço externo? E foi assim que fiz, transformando nossa modelagem anterior, pensada para as necessidades do software, em outra completamente diferente. Já dá para perceber o problema em que me meti.

3 - Rotina de Criação e Atualização

Outro ponto importante era a rotina de atualizações. Precisava buscar na API do provedor e filtrar pelos itens criados e alterados no dia, atualizando os dados com base no retorno de informações. Dessa forma, parece até bem simples, apenas criar um cron job que faça a requisição, não é mesmo? Na verdade, não.


Quando Percebi o Problema

Uma das coisas que aprendi nos últimos anos é que, quanto mais você planejar seu sistema visando o longo prazo, menos dor de cabeça terá. Todas as mudanças que fiz para adaptar o COSTPAT a essa nova realidade tiveram efeito positivo imediato: integração funcionando, cliente satisfeito e tudo fluindo como deveria. Até que começaram as solicitações de melhoria, muito comuns e nada incorretas da parte do contratante. Mas lembra que o código foi separado? Isso me fez:

  • Ter que atualizar o código dos dois back-ends.
  • Modificar a modelagem de dois bancos de dados.
  • Alterar o código de dois front-ends.

Então, para cada novo update, eu tinha o mesmo trabalho, duas vezes, já que boa parte deles fazia sentido para os outros clientes na que chamo de base compartilhada. Falando nisso, a base compartilhada continha o cadastro de usuários e unidades, ou seja, o front-end da prefeitura tinha que acessar dois back-ends distintos. Isso começou a se tornar uma grande bola de neve.

Outra questão que foi se tornando um problema com o tempo foi justamente a modelagem do banco de dados, já que o formato, a nomenclatura e uma série de outras questões de performance não me agradavam. Eu utilizava muito pouco o recurso de JOINS, denormalizei muitas informações que precisavam ter integridade, e isso exigiu muito do meu tempo para correções e updates manuais nas tabelas. Mas que, novamente, ainda daria para ‘levar’.

O estopim aconteceu quando a integração (atualizando os dados) começou a dar problema, ou seja, os dados do sistema já não estavam conseguindo ficar mais atualizados com o provedor. Isso ocorreu pelo fato de que, a cada semana, novas bases e volumes gigantescos de dados eram adicionados, fazendo com que uma requisição que era síncrona demorasse mais de 5 minutos para executar e, em caso de time out, a função parava de executar. E mesmo que continuasse, iria esgotar os recursos do banco de dados pelo excesso de leitura e escrita.

Foi nesse momento que mudei minha mentalidade e decidi resolver de uma vez por todas.


Decisões Erradas

Todos esses problemas vieram de uma série de decisões técnicas erradas, que, vendo de fora, podem até não ter uma conexão, mas têm. Na época, minha insegurança ainda era muito grande, e eu acabava pensando sempre no curto prazo, desacreditado no quão longe o sistema poderia ir. Como podemos ver, isso refletiu justamente nisso: chegou um momento em que o sistema estava limitado por ele mesmo.


Como Eu Resolvi

Agora, com mais confiança, preparo técnico e uma visão de longo prazo, resolvi atacar cada um desses pontos na raiz, focando em tornar o COSTPAT independente, sem amarras a outros softwares e podendo integrar com qualquer um sem complicações. Dessa forma, eu decidi, em 2024, refazer o sistema do completo zero. (Irei discorrer mais sobre esses desafios em outro post).

1 - Resolvendo a Infraestrutura

Primeiro de tudo, uma infraestrutura para todos, reduzir custos e tornar tudo uma única base de código foi uma decisão crucial para minha produtividade e gerenciamento. Claro que isso foi um longo processo de transição, mas que, após um ano de mudança, não me arrependo.

Saí de um código cheio de validações e formatos de dados diferentes para um padrão limpo e unificado.

2 - Resolvendo a Modelagem

O banco de dados, sem dúvidas, é um dos pontos cruciais de um software. Você pode mudar back-end, front-end, o que for, mas se seu banco está bagunçado e mal otimizado, não tem estratégia de cache ou algo do tipo que salve. Por isso, passei mais de 2 semanas focadas exclusivamente nessa tarefa, desenhando cada entidade, cada atributo e cada tipo de informação. Aproveitei bastante dos JOINs, que, obviamente, em escala e desempenho, trazem prejuízos, mas para meu tipo de software, a integridade de informações é crucial.

3 - Resolvendo a Integração

Agora, o meu maior desafio técnico até então: tornar a integração modular e escalável para uma quantidade gigantesca de dados. O primeiro passo foi criar uma tabela de integrações para cada entidade, ou seja, um sistema externo poderia ser integrado com patrimônio somente, outro só com produtos e assim por diante, de forma que, na rotina de sincronização, são consideradas somente as unidades/clientes que têm essa associação. Essa abordagem torna-se tão modular que o próprio cliente consegue desabilitar e habilitar sem trazer problemas nas informações registradas.

O segundo passo foi melhorar a performance da rotina de atualização. Para isso, o mais óbvio foi tornar a requisição assíncrona, ou seja, a chamada é feita e, por baixo dos panos, os dados são de fato processados. Para isso, precisei implementar pela primeira vez as famosas FILAS.

filas.png

O conceito é simples: as filas, que podem ser gerenciadas usando diversas ferramentas, como SQS e RabbitMQ, são como filas de um caixa de supermercado, onde uma requisição é processada (ou, no caso, os produtos são colocados nas bolsas) e, assim que é finalizada, é chamada a próxima requisição na fila. Enquanto esse processo acontece, as outras requisições que não são processadas em filas podem ser feitas normalmente.

Implementando esse conceito na minha aplicação, reduzi consideravelmente o estresse do banco de dados e tornei a resposta ao cron job praticamente instantânea.

Obviamente, como já citei no artigo passado, tudo em programação tem seus prós e contras, ou seja, não use filas para tudo, apenas quando necessário. Nessa funcionalidade, meu usuário não precisa da resposta no momento, de forma que posso avisar assim que o processo for concluído. Foi exatamente o que fiz: quando o processo finaliza, é enviado um e-mail para mim e meus sócios informando quantos itens foram processados, quantos falharam (caso falhe) e quantos passaram, além de salvar um log de todo o processo, para que eu consiga saber exatamente o que ocorreu.


Aprendizados

Esse foi um problema real, com uma solução real. De fato, os cursos na internet trazem informações técnicas que precisamos; é um embasamento importante, mas a grande parte dos aprendizados que tive como desenvolvedor vieram do campo de batalha!

Espero que, assim como foi comigo, essa história da vida real tenha te ajudado a ver o mundo da tecnologia com outros olhos e te motive a encarar os desafios que vêm pela frente. Aprendi muito sobre a área de desenvolvimento nesses últimos 4 anos atuando, mas os aprendizados mais importantes foram sobre mim e a capacidade de lidar com cada novo desafio sem desistir.

É isso, pessoal! Caso queiram conhecer mais sobre os desafios técnicos de desenvolver o COSTPAT do completo zero, comentem aqui embaixo. Até a próxima!

bye.gif