Camadas de Arquitetura Serverless 🚀
Tags: aws, serverless, webdev, braziliandevs
Published: 2022-09-21 05:33:39

_Foto de [Willian Justen de Vasconcellos](https://unsplash.com/@willianjusten?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) no [Unsplash](https://unsplash.com/s/photos/moutain-layers?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)_

**Como e por que acredito que as organizações corporativas devem usar o Design Orientado a Domínio (DDD) com as Cinco Camadas de Arquitetura Serverless, inspiradas no excelente trabalho de Eric Evans. Falaremos através de uma empresa fictícia usando camadas de arquitetura, com visuais e descrições.**

---

![Um exemplo das cinco camadas de arquitetura para Serverless](https://miro.medium.com/max/1400/1*zOX8bWSVzp7a3WeZPYWQ0A.png)
_Um exemplo das cinco camadas de arquitetura para Serverless_

## Introdução

Em arquitetura corporativa no mundo serverless, é imperativo planejarmos holisticamente e conceitualmente, nossas soluções gerais como um conjunto de padrões, modelos e proteções para garantir que não tenhamos uma [arquitetura anêmica de pinball lambda](https://www.thoughtworks.com/en-gb/radar/techniques/lambda-pinball) , que com o tempo se torna uma grande bola de lama e provavelmente um monólito distribuído com muita duplicação de lógica de negócios e esforço de equipe desperdiçado. ( _mostrado abaixo_ )

![O resultado é uma arquitetura de pinball em serverless e uma grande bola de lama durante a transformação de um projeto em serverless](https://miro.medium.com/max/1400/1*9SSUAfDBHKCcKmT88lmW7Q.png)

_O resultado é uma arquitetura de pinball em serverless e uma grande bola de lama durante a transformação de um projeto em serverless_

> "Arquiteturas de pinball lambda caracteristicamente perdem de vista a lógica de domínio, que é importante nessa teia emaranhada de lambdas, buckets e queues à medida que as solicitações percorrem em torno de gráficos cada vez mais complexos de serviços em nuvem." — Thoughtworks

Isso pode acontecer facilmente à medida que as organizações iniciam suas transformações Serverless com muitas novas equipes criando novas soluções em seus próprios silos ao longo do tempo, extrapolando isso rapidamente, pois muitas organizações também estão distribuídas globalmente e geograficamente. Junte isso com o [Conways Law](https://www.thoughtworks.com/insights/articles/demystifying-conways-law) e podemos rapidamente ter grandes problemas e retrabalho em massa escala.

Este artigo discute a Arquitetura em Camadas, que foi destacada por Eric Evans no livro [Domain-driven Design](https://tinyurl.com/rs7jap5r) . ( _Eu encorajo todos os arquitetos e desenvolvedores serverless a comprar este livro_ ), e o que isso significa no paradigma Serverless para empresas.

![Design orientado por domínio — Eric Evans](https://miro.medium.com/max/1400/1*z7XooSUeYqprARuYLYnEgg.png)

_Design orientado por domínio — Eric Evans: [https://tinyurl.com/rs7jap5r](https://tinyurl.com/rs7jap5r)_

Quando se trata de Serverless em organizações corporativas, acredito que se pareça mais com o diagrama abaixo, que mostra as "**Cinco Camadas de Arquitetura Serverless**":

![Um exemplo das cinco camadas de arquitetura para Serverless](https://miro.medium.com/max/1400/1*zOX8bWSVzp7a3WeZPYWQ0A.png)

_Um exemplo das cinco camadas de arquitetura para Serverless_

As seguintes camadas cruzaram do "mundo antigo de software" para o novo mundo Serverless (citaremos _o livro à medida que avançamos_ ):

- 🔵 **Interface do usuário (apresentação) e aplicativo → Experiência**
- 🔵 **Domínio → Domínios**
- 🔵 **Infraestrutura → Plataformas**

Durante este artigo, vamos entrar nas cinco camadas de arquitetura serverless, enquanto mostramos como as arquiteturas Serverless de nossa empresa fictícia, "(**Lee James Mountain Wear**)", se parecem ao usar essa abordagem ou não.

![Nossa empresa fictícia, Lee James Mountain Wear](https://miro.medium.com/max/1400/1*f5XIJkJSrECXJIqBDJQEow.png)

_Nossa empresa fictícia, Lee James Mountain Wear_

Também podemos combinar essa abordagem com o [Serverless TACTICAL DD(R)](https://levelup.gitconnected.com/serverless-tactical-dd-r-23d18d529fa1) e uma abordagem em toda empresa como [Tech Radar](https://www.thoughtworks.com/radar/byor), para garantir que tenhamos as proteções, padrões e governança de arquitetura relevantes à medida que as equipes migram para o Serverless durante uma transformação em toda a empresa; ao mesmo tempo que ainda permite inovação e arquiteturas evolutivas:

![Camadas de Arquitetura + TACTICAL DD(R) + Tech Radar](https://miro.medium.com/max/1400/1*PvCP621lApdk0VSjVWKZBA.png)

_Camadas de Arquitetura + TACTICAL DD(R) + Tech Radar_

https://levelup.gitconnected.com/serverless-tactical-dd-r-23d18d529fa1

https://www.thoughtworks.com/radar/byor

Vamos passar pelas várias camadas na próxima seção abaixo.

## Camada de Experiência 🏂

No livro, a **Interface do Usuário** ou **Camada de Apresentação** é descrita como "_Responsável por mostrar informações ao usuário e interpretar os comandos dos usuários_" e a **Camada de Aplicação** é descrita como "_Define os trabalhos que o software deve fazer e direciona os objetos de domínio expressivos para resolver problemas_".

> " _Define os trabalhos que o software deve fazer e direciona os objetos de domínio expressivos para resolver problemas_" — Eric Evans (Domain-Driven Design)

Ele continua falando sobre a camada de **aplicação**: "_Esta camada é mantida fina. Ela não contém regras de negócios ou conhecimento, mas apenas coordena tarefas e delega trabalhos para colaborações de objetos de domínio na próxima camada abaixo_".

> "_Esta camada é mantida fina. Ela não contém regras de negócios ou conhecimento, mas apenas coordena tarefas e delega trabalhos para colaborações de objetos de domínio na próxima camada abaixo_" — Eric Evans (Domain-Driven Design)

Podemos ver um exemplo no diagrama abaixo da **camada de experiência serverless**, composta por camadas de apresentação e de aplicativo, que normalmente é composto por experiências do usuário, como micro-frontends, [aplicativos Alexa](https://developer.amazon.com/en-US/alexa), websites (_talvez aplicativo React armazenado no Amazon S3_ ), aplicativos móveis etc; bem como APIs finas, chamadas de [de Backend para Frontend (](https://docs.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends) [_BFF_](https://docs.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends) [)](https://docs.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends) específicas, talvez usando [Amazon API Gateway](https://aws.amazon.com/api-gateway/) ou [AWS AppSync](https://aws.amazon.com/appsync/) .

![A camada de experiência](https://miro.medium.com/max/1400/1*SVOxDzZZ-fq0sA9T8fzM3g.png)

_A camada de experiência_

Essas APIs finas podem ter suas próprias necessidades de autenticação, por exemplo, um aplicativo interno pode usar [SSO](https://en.wikipedia.org/wiki/Single_sign-on) federado com o Azure AD, mas os aplicativos móveis e Alexa podem usar o [Amazon Cognito](https://aws.amazon.com/cognito/) para usuários externos dos sistemas.

Não deve haver lógica de negócios nessas APIs finas (_discutiremos o motivo mais tarde_), mas deve-se apenas se preocupar com a orquestração da funcionalidade de negócios necessária para a experiência utilizando a **Camada de Domínio**.

### Vamos ver um exemplo para nossa empresa fictícia

Podemos ver no diagrama abaixo que a equipe de estoque, que lida com o estoque de roupas de montanha, tem em sua arquitetura:

1.  Permitiu que a lógica de negócios vazasse no código de front-end para o sistema interno de verificação de estoque. Esta lógica não é acessível ao resto dos sistemas.
2.  Um aplicativo Alexa precisa adicionar funcionalidade para "verificar estoque online"; no entanto, essa lógica já foi duplicada nos dois back-end para front-end APIs, um para o sistema interno de verificação de estoque e outro para os websites que verificam o estoque.

![Exemplo de onde as equipes erraram imediatamente](https://miro.medium.com/max/1400/1*fhxoYxKXShmOAfikwVa-bA.png)

_Exemplo de onde as equipes erraram imediatamente_

**Resumo dos objetivos:**

- 🔵 Garantir que a lógica de negócios não vaze pela organização. (_Lambda Pinball_).
- 🔵 Garantir que a lógica de negócios seja reutilizável em toda a organização e camadas de experiência, não deve ficar em BFFs ou código de front-end.  
- 🔵 Permitir usar diferentes requisitos de autenticação por camada de experiência.  
- 🔵 A camada de experiência, ou seja, UI/Voice/UX, não deve conter lógica de negócios compartilhada.  
- 🔵 As APIs de back-end para front-end não devem conter estado (sem estado/stateless).

## Camada transversal 📐

Não há equivalente no livro para **Camada Transversal (cross-cutting layer)** , mas isso é algo que, na minha opinião, é imperativo ao arquitetar soluções corporativas serverless.

Exemplos de preocupações transversais são bibliotecas de componentes para desenvolvimento de front-end, envio de comunicações como e-mails e SMS e registro e rastreamento agregados, permitindo correlacionar registros em uma infinidade de serviços e chamadas. Outra seria a autenticação, pois nossos clientes devem ter uma experiência de SSO independentemente de usar um aplicativo Alexa, um Chatbot ou nosso site

![A camada transversal](https://miro.medium.com/max/1400/1*DQK-Uh7j4ETGDabaihOgSw.png)

_A camada transversal_

Como arquitetos, se não pensarmos nisso cedo como um grupo, quando começamos a arquitetar nossas soluções, descobrimos que as equipes individuais começam a enfrentar e resolver os mesmos problemas repetidamente; por exemplo, mais de uma equipe analisando a autenticação do cliente. (_mostrado abaixo_).

![A camada transversal](https://miro.medium.com/max/1400/1*G0qDhLgCV9BN61anYMXN3w.png)

_A camada transversal_

Isso leva as equipes a escolherem diferentes produtos SasS dentro de seus próprios silos, por exemplo, aumentando a carga cognitiva em novas equipes que são criadas (_resolvendo os mesmos problemas repetidamente_) e reduzindo a chance de obtermos melhores contratos com fornecedores em escala.

### Vamos ver um exemplo para nossa empresa fictícia

Em nosso exemplo para _Lee James Mountain Wear_, descobrimos que nossas equipes de estoque e pedidos estão construindo suas próprias bibliotecas de componentes React em seus próprios silos, pois há uma falta de comunicação, sem pensar nisso em nível empresarial.

Ao mesmo tempo, nossas equipes de clientes e pedidos estão fazendo um trabalho de POC em torno da observabilidade e conversando com dois fornecedores de SaaS diferentes. Extrapole isso à medida que o número de equipes cresce, bem como o aspecto global, e você tem alguns problemas sérios em escala (_mostrados abaixo_)

![Problemas quando não se pensa em preocupações transversais de forma holística](https://miro.medium.com/max/1400/1*VDjGYKNUB6INq_qf3YntYQ.png)

_Problemas quando não se pensa em preocupações transversais de forma holística_

**Resumo dos objetivos:**

- 🔵 Evita complexidade, duplicação e carga cognitiva em cada equipe resolvendo os mesmos problemas.  
- 🔵 Permita que as pessoas se movimentem com mais facilidade entre as equipes, pois temos padrões.  
- 🔵 Aumenta a velocidade e agilidade nas equipes sem reinventar a roda.  
- 🔵 Nos permite obter melhores contratos com fornecedores de produtos SasS devido ao aumento do uso em escala empresarial.

## Camada de Domínio 🛍️

A Camada de Domínio na minha opinião é a mais importante para acertar e focar. No livro, Eric Evans descreve isso como "_Responsável por representar conceitos para o negócio, informações sobre a situação do negócio e regras de negócio._".

> "Responsável por representar conceitos para o negócio, informações sobre a situação do negócio e regras de negócio" — Eric Evans (Domain-Driven Design)

Em um mundo serverless, isso seria representado normalmente usando API Gateways privados apoiados por [AWS Lambda](https://aws.amazon.com/lambda/) ou [AWS Fargate](https://aws.amazon.com/fargate/), especificamente com seu próprio armazenamento de dados, como [AWS DynamoDB](https://aws.amazon.com/dynamodb).

https://levelup.gitconnected.com/serverless-private-apis-60749934b161

A API deve ser bem definida e versionada usando [Open API ( _Swagger_ )](https://swagger.io/specification/) e deve se tornar a raiz agregada e a interface principal do domínio. Em sistemas orientados a eventos, também é imperativo que usemos eventos com versão bem definidos para fazer a interface com o domínio, por exemplo, usando o [Amazon EventBridge](https://aws.amazon.com/eventbridge/) com o [Schema Registry](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-schema.html) . Isso garante que possamos alterar os componentes internos do nosso serviço de domínio sem afetar os consumidores.

![A Camada de Domínios — lógica de negócios reutilizável](https://miro.medium.com/max/1400/1*EdWUCwkJx8ZjlKe9s1i10A.png)

_A Camada de Domínios — lógica de negócios reutilizável_

As partes internas do serviço de domínio devem ser encapsuladas para que não tenhamos outros domínios e equipes entrando em contato diretamente com nossos bancos de dados, por exemplo, ignorando a governança de nossas regras de negócios, logs e lógica (_como mostrado acima_).

![A Camada de Domínios — lógica de negócios reutilizável](https://miro.medium.com/max/1400/1*p-WDkLp6bKGt5neTPBFj5Q.png)

_A Camada de Domínios — lógica de negócios reutilizável_

Agora, isso significa que podemos reutilizar a lógica de negócios do domínio em várias camadas de experiência e outros domínios, usando o back-end fino para APIs de front-end para nossas APIs de domínio usando um fluxo de concessão de credenciais de cliente ( _machine to machine, como mostrado acima_).

https://levelup.gitconnected.com/serverless-api-to-api-authentication-d4cb4472721e

![A camada de domínios](https://miro.medium.com/max/1400/1*qX1mk41VWcqPHIdcV8YsRg.png)

Precisamos garantir que os domínios sejam bem encapsulados e que os serviços de domínio não comecem a interagir com os domínios internos de outros domínios, seja banco de dados ou tópicos internos do [AWS SNS](https://aws.amazon.com/sns/) ou filas do [Amazon SQS](https://aws.amazon.com/sqs/) (_como mostrado acima_). Se isso acontecer, irá desfazer todo o bom trabalho que fizemos na definição dos domínios e na criação de nossas interfaces com versão.

![A camada de domínios](https://miro.medium.com/max/1400/1*7dQDiq6PBzEz19_zngkFww.png)

Também devemos garantir que nossos serviços de domínio não sejam acessíveis ao mundo exterior, mesmo quando estiverem vinculados usando autenticação. (_como mostrado acima_).

Como as APIs devem ser protegidas em um fluxo de máquina para máquina, não há razão para que elas sejam acessíveis via Postman, curl, mobile, páginas da web etc. Elas nunca serão chamadas diretamente de um frontend, por exemplo, portanto, por motivos de segurança, elas devem ser protegidas de acordo (_consulte o artigo acima para APIs privadas na AWS_).

**Resumo dos objetivos:**

- 🔵 APIs e eventos versionados bem definidos garantem que os consumidores entendam como interagir com nossos domínios.  
- 🔵 Interfaces de domínio significam que podemos alterar as partes internas sem afetar os consumidores.  
- 🔵 Nossos serviços de domínio não são acessíveis externamente ao mundo, e apenas acessados ​​usando fluxos de máquina para máquina. (_ou seja, usando API Gateways privados_).  
- 🔵 Garantimos que os consumidores não interagem com serviços internos de nossos domínios, apenas por meio de nossas APIs e eventos bem definidos.  
- 🔵 A lógica de domínio pode ser utilizada por outros serviços, camadas de experiências e domínios, evitando que domínios anêmicos sejam divididos em um monólito distribuído.

## Camada de dados 📊

A próxima camada Serverless é a **camada de dados**, que não é representada no livro; no entanto, no mundo de dados de hoje e orientado a eventos, precisamos pensar sobre isso em um nível empresarial.

A camada de dados é normalmente composta por três áreas principais:

1.  **Enterprise Service Bus**: Por exemplo, normalmente seria Amazon EventBridge ou [Amazon MSK (Kafka)](https://aws.amazon.com/msk/) .
2.  **Relatórios e BI**: Por exemplo, normalmente seria [Amazon QuickSite](https://aws.amazon.com/quicksight/) e [Amazon Athena](https://aws.amazon.com/athena/) .
3.  **Dados**: Normalmente, seriam data lakes do [Amazon Redshift](https://aws.amazon.com/redshift/) ou do [S3,](https://aws.amazon.com/products/storage/data-lake-storage/) por exemplo.

Devemos governar isso em um nível de Arquitetura Corporativa (Enterprise Architecture) para garantir que tenhamos uma maneira de nossos serviços de domínio interagirem uns com os outros de maneira orientada a eventos em toda a organização e não tenhamos equipes diferentes usando tecnologias diferentes ( _SNS, Kafka, EventBridge etc_ ). Isso é abordado no artigo abaixo:

https://levelup.gitconnected.com/serverless-event-driven-systems-9617c6406064

A utilização de um _enterprise service bus_ como o Amazon EventBridge, significa que os domínios podem interagir uns com os outros usando eventos de versão bem definidos, bem como back-end para APIs de front-end na camada de experiência, também gerando eventos nos quais outros domínios podem estar interessados:

![A camada de dados](https://miro.medium.com/max/1400/1*n1RaTFqNJT7-7guGT0DRMA.png)

Isso é mostrado abaixo onde os domínios podem gerar eventos como "Pedido criado", "Preço alterado" etc; e Camadas de Experiência podem gerar eventos como "Usuário conectado".

![A camada de dados](https://miro.medium.com/max/1400/1*2Ug4VUugYX7tzODQDhF4yg.png)

Isso também nos permite construir nossos data lakes e agregar esses eventos para nos permitir ser mais orientados por dados, para que haja links intrínsecos entre eventos, dados e relatórios/BI. O artigo abaixo discute como utilizar fluxos e eventos para solucionar os problemas com confirmações de duas fases em um mundo sem servidor:

https://levelup.gitconnected.com/serverless-streamed-events-ada6ed9a9ecf

### Vamos ver um exemplo para nossa empresa fictícia

Na organização empresarial _Lee James Mountain Wear_, temos três equipes diferentes utilizando três tecnologias diferentes (_SNS, EventBridge e MSK_), o que dificulta muito a comunicação de domínio com base em eventos. A padronização em nível empresarial desde o início tornaria isso muito mais fácil, reduzindo o tempo de desenvolvimento, reduzindo a carga cognitiva nas equipes e permitindo esquemas de eventos com versão e descoberta de eventos.

![As equipes não têm padrão para comunicação de domínio e estão usando SNS, EventBridge e MSK.](https://miro.medium.com/max/1400/1*02a2UbDnQs4Lcg95bqm3eA.png)

_As equipes não têm padrão para comunicação de domínio e estão usando SNS, EventBridge e MSK._

**Resumo dos objetivos:**
- 🔵 Um Enterprise Service Bus nos permite coordenar eventos entre equipes de uma empresa.  
- 🔵 O Amazon EventBridge Schema Registry permite que outras equipes visualizem nossos eventos versionados e os consumam (_fácil de descobrir, reduzindo a carga cognitiva e aprimorando a comunicação_)
- 🔵 Podemos relatar os dados e eventos transmitindo-os para data lakes ou warehouses e consumindo usando ferramentas como Athena e QuickSite.  
- 🔵 Podemos usar análise de sentimentos e eventos para criar visualizações de clientes únicos.  
- 🔵 Reduz a carga cognitiva nas equipes que utilizam um ESB e aumenta sua velocidade e agilidade.

## Camada de plataformas 🌐

A camada final do livro, a **Camada de Infraestrutura**, é equivalente à **Camada de Plataformas**. No mundo serverless, as equipes estarão gerenciando sua própria arquitetura e serviços por meio de infraestrutura por código, ao invés do mundo tradicional de gerenciamento de servidores. O livro descreve a camada de infraestrutura como "_Fornece recursos técnicos genéricos que suportam as camadas superiores_".

> "_Fornece recursos técnicos genéricos que suportam as camadas superiores_" — Eric Evans (Domain-Driven Design)

No mundo serverless para equipes de desenvolvimento, isso normalmente é composto por:

1.  **Plataformas de Autenticação**: Essa é uma maneira padrão de equipes realizarem comunicação de máquina para máquina.
2.  **Pipelines e Contas**: As equipes serverless não precisam pensar no trabalho pesado, como criar pipelines ou criar VPCs, configurações de redes, gateways de trânsito etc. Isso deve ter templates para rápido uso pelas novas equipes/domínios.
3.  **Segurança**: A segurança deve ser incorporada o mais cedo possível em nossos modelos quando novas equipes e soluções são lançadas, movendo isso para a esquerda no fluxo de desenvolvimento, o mais rápido possível (conceito "shift-left").
4.  **Especificações da API/Esquemas de Eventos**: Eles devem ser centralizados e fáceis de serem descobertos pelas equipes, aumentando a agilidade e a velocidade.

Isso é mostrado no diagrama abaixo:

![A camada de plataformas](https://miro.medium.com/max/1400/1*gWVSTdFbo_1n3fAN7OiA_w.png)

O mais importante deles na minha opinião são **Pipelines e Contas**, pois equipes Serverless devem ter a capacidade de utilizar templates e arquiteturas de referência, com a plataforma essencialmente removendo o trabalho pesado diferenciado e reduzindo a carga cognitiva. Esses modelos também devem ter segurança incorporada, movendo a segurança para a esquerda o mais cedo possível.

Existem muitos produtos, como [AWS Proton](https://aws.amazon.com/proton/) e [Backstage IO](https://backstage.io/) , que realizam isso em nível empresarial.

## Resumo

- 🔵 Os portais e plataformas de desenvolvedores devem aumentar a velocidade e agilidade para as equipes Serverless.  
- 🔵 Definições de infraestrutura de baixo-nível como networking, configuração de VPCs, criação de pipelines etc devem ser fornecidos pela plataforma e com templates.  
- 🔵 Os portais do desenvolvedor devem facilitar para as equipes descobrirem APIs e definições de eventos.

# Créditos

- [Serverless Architecture Layers](https://levelup.gitconnected.com/serverless-architecture-layers-a9dc50e9b342), escrito originalmente por [Lee James Gilmore](https://twitter.com/LeeJamesGilmore).