TECTIUS
EN PT

Todos os insights

Fabric

De um problema de produto a uma plataforma reutilizável.

De um problema de produto a uma plataforma reutilizável.

Não partimos com a intenção de construir uma plataforma de backend. Quando começámos a desenvolver o ExME, a prioridade era simples: avançar depressa. Precisávamos das capacidades habituais de backend — autenticação, acesso à base de dados, gestão de ficheiros, envio de email e APIs — sem passar meses a construir infraestrutura antes de termos um produto.

Na altura, o DreamFactory encaixava bem. Era open source, não tinha custo de licença, e dava-nos muitas das capacidades de que precisávamos de origem. Para um produto em fase inicial, esse compromisso fazia sentido. Depois o ExME cresceu. E os pressupostos por trás dessa decisão começaram a mudar.

Quando o problema muda, a arquitetura tem de mudar

À medida que o ExME crescia em utilizadores e em complexidade, começámos a encontrar problemas de estabilidade e de escalabilidade. O problema não era simplesmente o sistema estar “lento”. O problema mais relevante era a eficiência de recursos. Estávamos a ver um consumo relativamente alto de recursos para a quantidade de pedidos a serem processados. A arquitetura que tinha sido perfeitamente adequada quando o produto era mais pequeno estava a tornar-se cada vez mais difícil de escalar com eficiência.

Ao mesmo tempo, os nossos requisitos de segurança dos dados estavam a tornar-se mais exigentes. Em particular, implementar o nível de segurança ao nível da linha e de controlo de acesso aos dados que queríamos exigia soluções de contorno cada vez mais complexas. Depois houve outra mudança: o modelo comercial da tecnologia deixou de corresponder à razão pela qual a tínhamos escolhido originalmente.

Nesse ponto, continuar com a mesma solução significava aceitar compromissos em várias áreas ao mesmo tempo:

  • escalabilidade;
  • consumo de recursos;
  • segurança e controlo de acesso aos dados;
  • complexidade operacional;
  • e custo.

Foi nesse ponto que deixámos de perguntar:

“Como é que fazemos esta solução funcionar?”

e passámos a perguntar:

“O que é que precisamos, de facto, do nosso backend?”

Construir apenas o que precisávamos

A resposta não era construir mais uma framework genérica de backend. Queríamos algo focado nos requisitos com que estávamos mesmo a lidar:

  • autenticação e autorização;
  • acesso controlado aos dados;
  • performance previsível;
  • gestão de ficheiros;
  • comunicação por email;
  • logging estruturado;
  • configuração;
  • escalabilidade;
  • e, importante, consistência entre aplicações.

Construímos o novo backend com Spring Boot, juntamente com um portal de configuração que permite gerir grande parte do comportamento da plataforma sem implementar repetidamente a mesma funcionalidade em cada aplicação. O objetivo não era criar mais uma stack tecnológica só por a ter. O objetivo era centralizar capacidades que se estavam a tornar comuns nas nossas aplicações.

Do backend do ExME ao Fabric

Inicialmente, o novo backend existia porque o ExME precisava dele. Isso mudou relativamente depressa. À medida que desenvolvíamos outras aplicações, íamos encontrando os mesmos requisitos:

  • Como devem os utilizadores autenticar-se?
  • Como deve uma aplicação aceder a um determinado dado?
  • Como devem os ficheiros ser guardados?
  • Como devem ser executadas operações que envolvem várias ações de backend?
  • Como devem as falhas ser registadas?
  • Como devem as aplicações ser configuradas de forma consistente?

Já tínhamos soluções para muitos destes problemas. Havia pouca razão para os resolver outra vez, de forma independente. Por isso o backend deixou de ser o backend do ExME e passou a ser algo mais geral: uma plataforma reutilizável para os nossos projetos de software.

Essa distinção importa. Reutilizar código é útil. Reutilizar decisões de arquitetura bem compreendidas é muito mais valioso.

A plataforma está a tornar-se um ecossistema

O Fabric está a evoluir para um conjunto de componentes especializados, em vez de uma aplicação grande responsável por tudo. Neste momento, três componentes definem a direção dessa arquitetura.

                         Fabric
                                │
             ┌──────────────────┼──────────────────┐
             │                  │                  │
          Heimdall             Saga               Ekko
       Authentication       Operations         Communication
             │                  │                  │
          Identity        Synchronous          Real-time
          Security          execution          + Push
                              │
                         Multiple steps

Cada componente tem uma responsabilidade específica.

Heimdall — Identidade e autenticação

O Heimdall é responsável pelo lado da identidade e da autenticação do ecossistema. Fornece a base comum para aplicações que precisam de saber:

  • quem é o utilizador;
  • se o utilizador está autenticado;
  • que acesso está disponível;
  • e como essa identidade se propaga pelo backend.

Esta é uma distinção importante para nós. A autenticação não devia ser algo que cada aplicação implementa de forma independente. É infraestrutura.

Saga — executar uma operação

O componente conhecido internamente como Pilot também evoluiu para além da ideia de um simples worker. O seu trabalho é executar operações compostas por vários passos.

Por exemplo: Enviar um email ao utilizador 2. Essa operação pode conter:

Operation: sendEmail

Step 1
  → Database
  → Get email address for user 2

Step 2
  → Email
  → Send message

Outra operação pode ser: Atualizar o avatar do utilizador 4.

Operation: uploadFileForAvatar

Step 1
  → Storage
  → Upload file

Step 2
  → Database
  → Store the resulting file reference

Os passos individuais podem ter tipos diferentes e interagir com capacidades diferentes do backend. Isto dá-nos um modelo de execução comum, em vez de implementar estas operações em várias fases separadamente dentro de cada aplicação. Estamos neste momento a usar este modelo para operações síncronas. A arquitetura também deixa espaço para uma capacidade futura de execução assíncrona, que se torna cada vez mais relevante à medida que o número e a complexidade das operações crescem.

Ekko — comunicar com os utilizadores

O Ekko é a próxima parte do ecossistema que estamos a desenvolver. A sua responsabilidade é a comunicação entre as nossas aplicações e os seus utilizadores, em particular quando a comunicação tem de acontecer em tempo real.

O modelo pretendido não é simplesmente: “Enviar uma notificação.” Está mais perto de:

Application
     │
     ▼
   Ekko
     │
     ├── Real-time communication
     │
     └── Push notification fallback

Se um utilizador estiver ligado ativamente, a comunicação pode acontecer pelo canal em tempo real. Se não estiver, o sistema pode recorrer a notificações push. Isto cria mais uma capacidade que as aplicações não deviam ter de implementar de forma independente.

Para onde a plataforma vai

Não vemos o Fabric como um produto acabado. Na verdade, uma das características úteis da plataforma é que o seu roadmap está a ser conduzido por problemas que encontramos de facto. A direção inclui neste momento áreas como:

Autenticação e autorização

Continuar a evoluir o modelo de identidade e de controlo de acesso entre aplicações.

Execução de operações

Alargar o conjunto de passos disponíveis e melhorar o controlo da execução, o tratamento de erros e a observabilidade.

Comunicação em tempo real

Concluir o Ekko e a sua integração com o recurso a notificações push.

Processamento assíncrono

Introduzir execução em segundo plano para operações que não devem ficar presas a um pedido síncrono. Isso vai introduzir outro conjunto de preocupações:

  • filas;
  • retries;
  • tratamento de falhas;
  • idempotência;
  • estado da execução;
  • monitorização.

Não são detalhes de implementação que se possam simplesmente acrescentar mais tarde sem pensar neles. Fazem parte da arquitetura.

Observabilidade

À medida que a plataforma se torna infraestrutura partilhada, perceber o que está a fazer torna-se cada vez mais importante. O logging é apenas o ponto de partida. Precisamos de conseguir perceber:

  • o que aconteceu;
  • quando aconteceu;
  • onde aconteceu;
  • o que falhou;
  • e o que aconteceu a seguir.

Porque é que construímos isto nós próprios?

Esta é provavelmente a pergunta que devemos fazer de forma explícita. A lição não é:

“Construir em vez de comprar.”

Não acreditamos nisso. A decisão original de usar um backend existente era razoável. Construir autenticação, gestão de ficheiros, envio de email e APIs de raiz antes de o ExME ter validado os seus próprios requisitos não teria sido necessariamente uma melhor decisão de engenharia.

A lição foi outra. A arquitetura certa pode mudar à medida que o problema muda. No início, usar uma plataforma existente deu-nos velocidade. Mais tarde, a mesma plataforma introduziu restrições de escalabilidade, consumo de recursos, segurança e custo.

Construir o nosso próprio backend passou a justificar-se porque já não estávamos a resolver um problema isolado. Estávamos a resolver a mesma classe de problemas em várias aplicações. Isso mudou a economia e a arquitetura.

A plataforma não é o produto

Há outro princípio por trás do Fabric que é talvez mais importante do que a própria tecnologia. Não queremos que as aplicações existam simplesmente para demonstrar a plataforma. O contrário é que é verdade. A plataforma existe para tornar as aplicações mais fáceis de construir, operar e fazer evoluir.

Isso significa que não queremos ditar tecnologia só porque calhámos de ter construído algo internamente. Se uma tecnologia diferente for melhor para um problema concreto, devemos usá-la. A plataforma deve retirar complexidade desnecessária, não criar uma nova forma dela.

De um problema a uma plataforma

A evolução pode portanto resumir-se de forma bastante simples:

ExME
  │
  │ Need to move quickly
  ▼
Existing backend platform
  │
  │ ExME grows
  │
  ├── Scalability constraints
  ├── Resource consumption
  ├── Security requirements
  ├── Data access complexity
  └── Commercial model changes
  │
  ▼
Fabric
  │
  ├── Heimdall
  │     Identity & Authentication
  │
  ├── Saga
  │     Operation execution
  │
  └── Ekko
        Real-time communication
        + Push fallback
  │
  ▼
Reusable platform
  │
  └── Multiple applications

Não partimos com um plano para construir uma plataforma de backend. Partimos a tentar resolver um problema. A plataforma surgiu quando percebemos que o problema não era único do ExME.

E essa é provavelmente a lição de arquitetura mais importante desta história: Boa arquitetura não é tomar a decisão certa uma vez. É reconhecer quando o problema mudou — e estar disposto a mudar com ele.