<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: José Roberto Araújo</title>
    <description>The latest articles on DEV Community by José Roberto Araújo (@jraraujo).</description>
    <link>https://dev.to/jraraujo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F304997%2F184fc3dc-362b-45a7-a078-df0735d79084.jpeg</url>
      <title>DEV Community: José Roberto Araújo</title>
      <link>https://dev.to/jraraujo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jraraujo"/>
    <language>en</language>
    <item>
      <title>Vertical Slice: Um Déjà Vu do CQRS</title>
      <dc:creator>José Roberto Araújo</dc:creator>
      <pubDate>Wed, 29 May 2024 14:30:26 +0000</pubDate>
      <link>https://dev.to/emergingcode/vertical-slice-um-deja-vu-do-cqrs-1458</link>
      <guid>https://dev.to/emergingcode/vertical-slice-um-deja-vu-do-cqrs-1458</guid>
      <description>&lt;p&gt;No cenário em constante evolução da arquitetura de software, certos padrões emergem para enfrentar desafios específicos na construção de aplicações sustentáveis, escaláveis e eficientes. Dois desses padrões são Command Query Responsibility Segregation (CQRS) e Vertical Slice Architecture. Embora o CQRS tenha sido uma abordagem de design proeminente por vários anos, a Vertical Slice Architecture, popularizada por Jimmy Bogard, ganhou força por sua metodologia pragmática e focada em capacidades de negócio e funcionalidades de negócio. &lt;/p&gt;

&lt;p&gt;Este post traça um paralelo entre a história e as motivações por trás do CQRS, explora o conceito de arquitetura Vertical Slice e compara esses dois padrões usando exemplos de código C# e organização de soluções do Visual Studio.&lt;/p&gt;

&lt;h2&gt;
  
  
  A origem e motivações por trás do CQRS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  O Surgimento do CQRS
&lt;/h3&gt;

&lt;p&gt;Fundamentado no &lt;a href="https://en.wikipedia.org/wiki/Command%E2%80%93query_separation" rel="noopener noreferrer"&gt;CQS&lt;/a&gt;, criado por &lt;a href="https://en.wikipedia.org/wiki/Bertrand_Meyer" rel="noopener noreferrer"&gt;Bertrand Meyer&lt;/a&gt;, Command Query Responsibility Segregation (&lt;a href="https://en.wikipedia.org/wiki/Command_Query_Responsibility_Segregation" rel="noopener noreferrer"&gt;CQRS&lt;/a&gt;) é um padrão arquitetural introduzido por &lt;strong&gt;Greg Young&lt;/strong&gt; por volta de &lt;strong&gt;2010&lt;/strong&gt;. O CQRS foi concebido para resolver vários problemas inerentes às arquiteturas tradicionalmente monolíticas e em camadas, onde as várias operações estavam implementadas em uma única base de código e muitas vezes uma única classe continha várias operações de leitura e escrita aninhadas, fornecendo vários tipos de operações sem separação de responsabilidades.&lt;/p&gt;

&lt;p&gt;As arquiteturas tradicionais geralmente combinam operações de leitura e gravação na mesma base de código e modelos de dados, levando a uma lógica que, muitas vezes, pode se tornar complexa de manter e também muito acoplada, tornando difícil a manutenção e evolução do sistema.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problemas resolvidos pelo CQRS
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Separação de preocupações&lt;/strong&gt;: Ao segregar comandos (&lt;em&gt;escrita&lt;/em&gt;) de consultas (&lt;em&gt;leituras&lt;/em&gt;), o CQRS promove uma separação clara de responsabilidades. Essa separação permite que os desenvolvedores otimizem e dimensionem as operações de leitura e gravação de forma independente, resultando em um código mais eficiente e de fácil manutenção.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Otimização de desempenho&lt;/strong&gt;: Em muitas aplicações, as operações de leitura giram em torno de 95% das tarefas executadas por um sistema, e apenas 5% do restante das operações são de gravação. O CQRS permite otimizar modelos de leitura separadamente dos modelos de gravação, muitas vezes levando a ganhos significativos de desempenho.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalabilidade&lt;/strong&gt;: Com o CQRS, diferentes partes do sistema podem ser dimensionadas de forma independente. Por exemplo, um aplicativo com muita leitura pode expandir seus componentes de leitura sem afetar o lado de gravação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gerenciamento de complexidade&lt;/strong&gt;: o CQRS facilita o gerenciamento de validações e lógicas de negócios complexas no lado da gravação, mantendo o lado da leitura simples e otimizado para consultas.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Não é uma regra ter que separar as instâncias de sua aplicação em uma instância de leitura e uma outra de escrita (gravação). essa abordagem pode acontecer, mas apenas em casos em que a performance do sistema demande essa separação física dos componentes. Aplicar CQRS em sua essência e em seu último nível de implementação arquitetural, vai introduzir um alto grau de complexidade para dentro da solução da sua arquitetura. Por isso, não seja purista aplicando 100% do que você leu e aprendeu sobre esse padrão arquitetural, analise e pense qual é o nível de abstração e implementação que o seu sistema demanda do padrão CQRS!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Sistemas CRUD-Based ofuscam a modelagem de um sistema
&lt;/h2&gt;

&lt;p&gt;Existem muitos sistemas que ainda estão sendo construídos com base no fundamento de servir aos clientes (eg.: &lt;em&gt;Frontend&lt;/em&gt;), apenas o DTO que é usado no lado servidor, afim de simplificar o processo de desenvolvimento, buscando acelerar a entrega de funcionalidades no mercado.&lt;/p&gt;

&lt;p&gt;Esse tipo de abordagem, conduz não só os desenvolvedores do sistema, mas também implica, negativamente, no desenho das telas, levando a uma UI/UX a terem funcionamento atômico, onde o comportamento das funcionalidades se resumem à apenas uma ação que estimule um sistema a recolher todas as alterações feitas na tela (UI/UX), envie para o servidor o DTO alterado, implicando, no final do processamento, persistir esses dados alterados em alguma base de dados.&lt;/p&gt;

&lt;p&gt;Através dessa abordagem, muitos pontos de design - não apenas de UI/UX, como também de software e modelagem de negócio, ficaram perdidos ao longo de todo o processo de desenvolvimento, testes e definição de negócio. Uma importante definição de negócio, a qual deveria levar em consideração: as &lt;strong&gt;intenções&lt;/strong&gt;, nesse modelo de desenvolvimento são facilmente deixadas de lado. Se fossem melhor melhor exploradas, poderiam resultar delimitação do escopo das ações em um formato mais bem definido, tornando, inclusive, mais fácil a implementação de sistemas ou parte de sistemas que se baseiam em CRUD.&lt;/p&gt;

&lt;p&gt;Abaixo tem uma tela de um perfil de usuário, como exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuu0t07hkf7rptieryovw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuu0t07hkf7rptieryovw.png" alt="CRUD-Based"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Através dessa imagem, é fácil notar que a intenção dessa tela é gerir, de uma maneira geral, o perfil de um usuário. Tornando difícil de descobrir qual foi a real intenção que um usuário teve, ao clicar no botão &lt;strong&gt;salvar.&lt;/strong&gt; Isso porque o frontend vai capturar todos os dados que existirem na tela e vai enviar, de volta para o servidor. Com isso o rastreamento da operação fica ofuscado pela modelagem CRUD-Based.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interface de usuário baseada em tarefas
&lt;/h2&gt;

&lt;p&gt;A ideia básica por trás de uma UI baseada em tarefas ou indutiva, é descobrir como os usuários desejam usar o software e fazer com que ele os oriente nesses processos. O objetivo é orientar o usuário durante o processo.&lt;/p&gt;

&lt;p&gt;Um software desenhado com base em uma interface baseada em tarefas adotaria uma abordagem diferente, provavelmente separaria as ações de gestão de dados pessoais, endereço e dados de cobrança em seções diferentes, onde cada uma delas pudessem demonstrar a intenção sobre a ação desejada. A intenção do usuário é clara neste caso e o software está guiando os seus passos através do processo de gestão de cada parte da informação de forma isolada, porém contextualizada dentro do perfil do usuário. Dessa forma, as ações podem ser usadas para a criação de comandos que representam as intenções do usuário com este estilo de interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpypvoqes8asbp40winc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpypvoqes8asbp40winc.png" alt="Task-based"&gt;&lt;/a&gt;&lt;br&gt;
A tela acima contém uma ação para gestão de dados pessoais!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fox6oitvdu96at7lnkwh4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fox6oitvdu96at7lnkwh4.png" alt="Task-based"&gt;&lt;/a&gt;&lt;br&gt;
A tela acima contém uma ação para gestão de dados de cobrança!&lt;/p&gt;

&lt;h2&gt;
  
  
  Capacidades de negócio + Funcionalidades de negócio:
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;em&gt;Todo sistema é construído com base em uma necessidade de negócio, a qual demanda que esse produto seja orientado às capacidades de negócio destinadas a resolver um problema específico de um dado plano de negócio, em um dado nicho de mercado, e também aborda quais serão as funcionalidades de negócio definidas para cada uma dessas capacidades.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Um sistema de &lt;strong&gt;Consultas Veterinárias&lt;/strong&gt;, pode ter como capacidades de negócio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Agendamento de consulta&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Histórico médico&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Acompanhamento de tratamentos&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cobrança&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E cada uma dessas capacidades pode conter diversas funcionalidades, como por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Histórico médico&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Revisar o histórico do paciente&lt;/li&gt;
&lt;li&gt;Atualizar o histórico do paciente&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Agendamento de consulta&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Procurar veterinário disponível&lt;/li&gt;
&lt;li&gt;Agendar consulta&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Implementação básica de CQRS
&lt;/h3&gt;

&lt;p&gt;Vamos voltar um pouco ao contexto do exemplo das imagens acima. Em uma implementação típica de CQRS, comandos são usados para realizar operações de gravação e consultas são usadas para recuperar dados que representam o estado atual de uma parte do sistema. Aqui está um exemplo simples em C#:&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo de um Comando (Command):
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AtualizarDadosPessoaisCommand&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ClienteId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;DataNascimento&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AtualizarDadosPessoaisCommandHandler&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IClienteRepositorio&lt;/span&gt; &lt;span class="n"&gt;_clienteRepositorio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AtualizarDadosPessoaisCommandHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IClienteRepositorio&lt;/span&gt; &lt;span class="n"&gt;clienteRepositorio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_clienteRepositorio&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clienteRepositorio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AtualizarDadosPessoaisCommand&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dadosPessoais&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ClienteDadosPessoais&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ClienteId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClienteId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Nome&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;DataNascimento&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataNascimento&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;_clienteRepositorio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AtualizarDadosPessoais&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dadosPessoais&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Exemplo de uma Consulta (Query):
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ObterClientePorIdQuery&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ClienteId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ObterClientePorIdQueryHandler&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IClienteRepositorio&lt;/span&gt; &lt;span class="n"&gt;_clienteRepositorio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ObterClientePorIdQueryHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IClienteRepositorio&lt;/span&gt; &lt;span class="n"&gt;clienteRepositorio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_clienteRepositorio&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clienteRepositorio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Cliente&lt;/span&gt; &lt;span class="nf"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ObterClientePorIdQuery&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_clienteRepositorio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ObterPorId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClienteId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Uma solução arquitetural que adota os conceitos CQRS, normalmente carrega como base de definição uma organização de projeto seguindo &lt;strong&gt;capacidades de negócio&lt;/strong&gt;, detalhando as &lt;strong&gt;funcionalidades intrínssicas&lt;/strong&gt; dentro de cada uma dessas capacidades. Abaixo, deixo um exemplo de organização de solução onde está explicitamente citada a capacidade de &lt;em&gt;gestão de perfil de cliente (usuário)&lt;/em&gt; e quais são as funcionalidades que compõe essa capacidade. Essa abordagem permite que um projeto de software seja fácil de ser compreendido tanto do ponto de vista sobre QUE PROBLEMA ele está resolvendo e COMO está organizada a base de código dessa solução, além, também, de facilitar a compreensão sobre que tipo de padrão está sendo adotado em sua implementação.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;.sln (solution)&lt;br&gt;
├── Capacidades-de-negocio&lt;br&gt;
│   ├── PerfilCliente&lt;br&gt;
│   │   ├── AtualizarDadosPessoais&lt;br&gt;
│   │   │   ├── AtualizarDadosPessoaisCommand.cs&lt;br&gt;
│   │   │   ├── AtualizarDadosPessoaisCommandHandler.cs&lt;br&gt;
│   │   │   └── AtualizarDadosPessoaisResponse.cs&lt;br&gt;
│   │   ├── AtualizarDadosCobranca&lt;br&gt;
│   │   │   ├── AtualizarDadosCobrancaCommand.cs&lt;br&gt;
│   │   │   ├── AtualizarDadosCobrancaCommandHandler.cs&lt;br&gt;
│   │   │   └── AtualizarDadosCobrancaResponse.cs&lt;br&gt;
│   │   ├── ObterClientePorId&lt;br&gt;
│   │   │   ├── ObterClientePorIdQuery.cs&lt;br&gt;
│   │   │   ├── ObterClientePorIdQueryHandler.cs&lt;br&gt;
│   │   │   └── ObterClientePorIdResponse.cs&lt;br&gt;
│   ├── ...&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Introdução à arquitetura Vertical Slice&lt;br&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  O que é esse tipo de arquitetura?
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://www.jimmybogard.com/vertical-slice-architecture/" rel="noopener noreferrer"&gt;Arquitetura Vertical Slice&lt;/a&gt;, defendida por &lt;a href="https://www.jimmybogard.com/" rel="noopener noreferrer"&gt;Jimmy Bogard&lt;/a&gt;, é um padrão que estrutura o código por capacidades de negócio e suas funcionalidades intrínssicas e não com base em CRUD-based. Essa abordagem promove o encapsulamento de todos os aspectos de um recurso (UI, lógica de negócios e acesso a dados) em uma única fatia vertical. Cada slice (fatia) é independente, tornando o sistema mais modular e mais fácil de manter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principais vantagens da arquitetura Vertical Slice
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Foco em capacidades e funcionalidades de negócio&lt;/strong&gt;: a organização do código é definida pelas capacidades e funcionalidades de negócio, alinhada à forma como os usuários finais percebem o aplicativo, tornando-o mais intuitivo para os desenvolvedores trabalharem em funcionalidades específicas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolamento e Modularidade&lt;/strong&gt;: Cada slice (&lt;em&gt;fatia&lt;/em&gt;) é isolada umas das outras, reduzindo o risco de efeitos colaterais não intencionais ao modificar um recurso.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maior capacidade de manutenção&lt;/strong&gt;: Unidades de código menores e independentes são mais fáceis de entender, testar e refatorar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desenvolvimento Paralelo&lt;/strong&gt;: As equipes podem trabalhar em diferentes fatias simultaneamente, sem atrapalhar umas às outras, acelerando o desenvolvimento.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementação do Vertical Slice
&lt;/h3&gt;

&lt;p&gt;Na arquitetura Vertical Slice, cada recurso inclui tudo o que precisa para funcionar: comandos, consultas, manipuladores e, às vezes, até mesmo a camada de acesso ao banco de dados. A partir desse ponto, começamos a ter um &lt;strong&gt;Dèjá Vu&lt;/strong&gt; sobre a perspectiva com a qual o Vertical Slice orienta a organização da solução, nos levando de volta à como o CQRS também organiza uma solução de projeto de software, baseando-se em capacidades e funcionalidades de negócio.&lt;/p&gt;

&lt;p&gt;Reaproveitando o mesmo contexto de negócio que foi utilizado para exemplificar o CQRS, veja como você pode organizar uma solução em seu projeto de software, usando Vertical Slice:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;p&gt;.sln (solution)&lt;br&gt;
├── Capacidades-de-negocio&lt;br&gt;
│   ├── PerfilCliente&lt;br&gt;
│   │   ├── AtualizarDadosPessoais&lt;br&gt;
│   │   │   ├── AtualizarDadosPessoaisCommand.cs&lt;br&gt;
│   │   │   ├── AtualizarDadosPessoaisCommandHandler.cs&lt;br&gt;
│   │   │   └── AtualizarDadosPessoaisResponse.cs&lt;br&gt;
│   │   ├── AtualizarDadosCobranca&lt;br&gt;
│   │   │   ├── AtualizarDadosCobrancaCommand.cs&lt;br&gt;
│   │   │   ├── AtualizarDadosCobrancaCommandHandler.cs&lt;br&gt;
│   │   │   └── AtualizarDadosCobrancaResponse.cs&lt;br&gt;
│   │   ├── ObterClientePorId&lt;br&gt;
│   │   │   ├── ObterClientePorIdQuery.cs&lt;br&gt;
│   │   │   ├── ObterClientePorIdQueryHandler.cs&lt;br&gt;
│   │   │   └── ObterClientePorIdResponse.cs&lt;br&gt;
│   ├── ...&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Comparação: CQRS vs. Vertical Slice&lt;br&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Semelhanças
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Separação de capacidades e funcionalidades de negócio&lt;/strong&gt;: Tanto o CQRS quanto o Vertical Slice enfatizam a separação por capacidades e funcionalidades de negócio dentro de uma solução, resultando em um código mais limpo e de fácil manutenção.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modularidade&lt;/strong&gt;: Cada abordagem promove a modularidade, facilitando o dimensionamento e a modificação de partes do sistema de forma independente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Foco em tarefas&lt;/strong&gt;: A arquitetura Vertical Slice, assim como o CQRS, é orientada pela implementação específica de tarefas, garantindo que o código seja organizado em torno das funcionalidades de negócios.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Diferença
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Gerenciamento de Complexidade&lt;/strong&gt;: Dependendo do grau de demanda de escalabilidade de um sistema, o que pode levar a implementação do último nível do CQRS, pode introduzir complexidade adicional devido à abordagem de separação das instâncias de escrita e leitura, implicando em uma solução que precisaria lidar com consistência eventual. O Vertical Slice visa reduzir a complexidade, mantendo o código relacionado junto na mesma fatia.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Tanto o CQRS quanto a arquitetura Vertical Slice oferecem paradigmas valiosos para estruturar aplicações modernas. O CQRS é excelente em cenários onde as operações de leitura e gravação precisam ser otimizadas de forma independente e podem lidar com lógica de negócios complexa de forma eficaz. A Arquitetura Vertical Slice, por outro lado, fornece uma abordagem mais intuitiva e de fácil manutenção, organizando o código em torno de recursos, facilitando o desenvolvimento e o gerenciamento.&lt;/p&gt;

&lt;p&gt;Ao compreender os pontos fortes e as nuances de cada padrão, os desenvolvedores podem escolher a arquitetura mais apropriada para suas necessidades específicas, resultando em aplicativos mais robustos e de fácil manutenção. Quer você opte pela separação estrita de preocupações oferecida pelo CQRS ou pela modularidade focada em recursos do Vertical Slice, ambos os padrões fornecem ferramentas poderosas para o desenvolvimento de software moderno.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cqrs.wordpress.com/wp-content/uploads/2010/11/cqrs_documents.pdf" rel="noopener noreferrer"&gt;Greg Young CQRS Documents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jimmybogard.com/vertical-slice-architecture/" rel="noopener noreferrer"&gt;Vertical Slice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cqrs</category>
      <category>verticalslice</category>
      <category>arquiteturadesoftware</category>
      <category>cqs</category>
    </item>
    <item>
      <title>Scalar: Documentação OpenAPI Moderna</title>
      <dc:creator>José Roberto Araújo</dc:creator>
      <pubDate>Fri, 24 May 2024 14:34:35 +0000</pubDate>
      <link>https://dev.to/emergingcode/scalar-documentacao-openapi-moderna-3a8j</link>
      <guid>https://dev.to/emergingcode/scalar-documentacao-openapi-moderna-3a8j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Swagger é uma das ferramentas mais utilizadas para documentação de APIs, mas seu tempo pode estar chegando ao fim com a chegada do Scalar UI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Contexto histórico do Swagger
&lt;/h2&gt;

&lt;p&gt;A história de uso do Swagger como ferramenta para documentação OpenAPI começa com a sua criação em 2010 por Tony Tam, enquanto trabalhava na empresa Reverb Technologies. Desde o início, seu objetivo era simplificar o processo de documentação de APIs para desenvolvedores.&lt;/p&gt;

&lt;p&gt;Com o Swagger, era possível criar uma interface amigável para APIs RESTful, permitindo aos desenvolvedores entender o funcionamento de uma API sem precisar mexer no código fonte. Além disso, o Swagger também permite testar a API diretamente no navegador, o que economiza tempo e esforço dos desenvolvedores.&lt;/p&gt;

&lt;p&gt;Em 2015, a Swagger foi doada para a Linux Foundation e se tornou parte do projeto OpenAPI. Juntamente com outras ferramentas, o Swagger ajudou a definir o padrão OpenAPI para documentação de APIs. Resultando na UI que já estamos acostumados a trabalhar por anos:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqmsa3d1hrvqk2rdoxmk6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqmsa3d1hrvqk2rdoxmk6.png" alt="Swagger UI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apesar de sua popularidade e amplo uso, a UI do Swagger também tem suas limitações. Por exemplo, durante todo esse tempo a UX do Swagger permaneceu praticamente a mesma, além de não permitir uma documentação que contivesse textos explicativos sobre os endpoints da API.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Scalar como alternativa na documentação OpenAPI&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O Scalar é uma ferramenta que vem servir como alternativa para documentação de APIs usando a especificação OpenAPI. Lançado recentemente, o Scalar se destaca por sua interface de usuário moderna e intuitiva, permitindo criar documentações contendo textos declarativos e explicativos sobre o negócio, funcionalidades, payloads e muitas outras formas de documentar uma API. &lt;/p&gt;

&lt;p&gt;A interface do Scalar é limpa e simplificada, tornando-a mais acessível para qualquer pessoa que tenha interesse ou precise entender quais funcionalidades estão disponíveis em uma API. Além disso, o Scalar é mais rápido que o Swagger para documentar APIs complexas, graças ao seu eficiente mecanismo de renderização, além de disponibilizar opções de exemplos de uso das APIs em diversas linguagens e plataformas, o que traz bastante facilidade para quem está querendo usar uma API.&lt;/p&gt;

&lt;p&gt;A integração do Scalar com a especificação OpenAPI significa que é possível importar e exportar documentação de API no formato OpenAPI, seja no formato &lt;strong&gt;json&lt;/strong&gt; ou no formato &lt;strong&gt;yaml&lt;/strong&gt;. Isso facilita a transição de outras ferramentas para o Scalar.&lt;/p&gt;

&lt;p&gt;O Scalar também oferece integração com várias outras plataformas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.NET&lt;/li&gt;
&lt;li&gt;GO&lt;/li&gt;
&lt;li&gt;Rust&lt;/li&gt;
&lt;li&gt;NestJS&lt;/li&gt;
&lt;li&gt;Dentre outras que pode ser encontradas no &lt;a href="https://github.com/scalar/scalar" rel="noopener noreferrer"&gt;repositório oficial do projeto&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Durante esse artigo, vamos demonstrar o uso do Scalar em um projeto AspNet Core usando .NET 8.0.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Habilitando Scalar UI em um projeto AspNet Core&lt;/strong&gt;  🚀
&lt;/h2&gt;

&lt;p&gt;Para demonstrar o uso do Scalar em um projeto .NET, vamos considerar um projeto AspNet Core simples usando &lt;strong&gt;.NET 8.0&lt;/strong&gt;, e que vai conter uma API para um sistema de gestão de hotéis.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Se você está rodando seus projetos já usando o .NET 9.0, a versão do Scalar a ser usada será um outro pacote com um nome diferente do apresentado neste artigo, disponível no &lt;a href="https://www.nuget.org/packages/Scalar.AspNetCore" rel="noopener noreferrer"&gt;Nuget&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A versão que pode ser usada com o .NET 8.0 pode ser ou a &lt;strong&gt;1.0.0&lt;/strong&gt; ou a &lt;strong&gt;1.0.1-rc&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Primeiro, precisamos adicionar o pacote Scalar ao nosso projeto através do NuGet:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;AspNetCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scalar&lt;/span&gt; &lt;span class="p"&gt;--&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="m"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Em seguida, podemos configurar o Scalar em nosso arquivo Program.cs:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseScalar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Theme&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RoutePrefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"api-docs"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;No trecho de código acima, estamos configurando o Scalar para servir nossa documentação de API na rota "&lt;strong&gt;/api-docs&lt;/strong&gt;".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Para usar o Scalar você não precisa desinstalar o Swagger do seu projeto, pois ambos conseguem conviver lado a lado. Se você já tem o swagger instalado no seu projeto, basta instalar o pacote do Scalar e adicionar o código acima e o pacote vai saber localizar a Url Path do swagger contendo a documentação da API no formato OpenAPI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finalmente, podemos acessar nossa documentação de API navegando para "&lt;a href="http://localhost:5096/api-docs" rel="noopener noreferrer"&gt;http://localhost:[PORTA_DEFINIDA]/scalar-api-docs&lt;/a&gt;" em um navegador de sua preferência. A partir daí, podemos interagir com nossa API diretamente da interface do Scalar.&lt;/p&gt;

&lt;p&gt;Esse exemplo ilustra um pouco do que o Scalar pode trazer de melhorias para a documentação da API do seu projeto. Com sua interface moderna e recursos poderosos, o Scalar é uma excelente alternativa ao Swagger para documentação OpenAPI.&lt;/p&gt;

&lt;p&gt;A imagem abaixo mostra o resultado da integração do Scalar em uma aplicação AspNet Core:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4kc5m8qn6rpsdh67ocm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr4kc5m8qn6rpsdh67ocm.png" alt="Scalar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perceba que a UI oferece uma experiência de usabilidade bastante diferente do que se está acostumado a ver com o Swagger. Além da UX diferente, também é possível realizar navegação pelas APIs e escolher uma plataforma para que o Scalar possa gerar um exemplo de código que se ajuste a sua necessidade, através das &lt;strong&gt;&lt;em&gt;Client Libraries&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scalar, .NET 9.0 e OpenAPI
&lt;/h2&gt;

&lt;p&gt;O time do AspNet Core está trabalhando na implementação de um pacote oficial da Microsoft, o qual vai trabalhar entregando 100% das especificações OpenAPI. Nesse sentido, o pacote &lt;em&gt;Swashbuckle&lt;/em&gt; será removido ❌ a partir do .NET 9.0, passando somente a ser possível utilizar o novo pacote: &lt;strong&gt;Microsoft.AspNetCore.OpenApi.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O pacote Scalar.AspNetCore, a partir da versão 1.0.1, será possível se integrar com as novidades que virão junto com o .NET 9.0 e a nova API de documentação, que trás um nome bastante óbvio: &lt;strong&gt;&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/aspnetcore-openapi?view=aspnetcore-9.0&amp;amp;tabs=visual-studio#using-scalar-for-interactive-api-documentation" rel="noopener noreferrer"&gt;Microsoft.AspNetCore.OpenApi&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Validando sua especificação usando: &lt;em&gt;Spectral&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Spectral é um linter de documentos OpenAPI de código aberto. O pacote &lt;strong&gt;Spectral&lt;/strong&gt; pode ser incorporado à construção de seu aplicativo para verificar a qualidade dos documentos OpenAPI gerados. Para instalar o Spectral siga as instruções através do &lt;a href="https://github.com/stoplightio/spectral" rel="noopener noreferrer"&gt;repositório oficial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para tirar vantagens do Spectral você precisa realizar algumas configurações e instalar um pacote no seu projeto, antes de utilizar a ferramenta de Linter. Instale o pacote  Microsoft.Extensions.ApiDescription.Server, ele vai permitir que seja gerada a documentação OpenAPI no momento do build do projeto.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Extensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ApiDescription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt; &lt;span class="p"&gt;--&lt;/span&gt;&lt;span class="n"&gt;prerelease&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Configure o seu projeto para gerar documentos no momento da compilação definindo as seguintes propriedades no arquivo &lt;strong&gt;.csproj&lt;/strong&gt; do seu aplicativo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;OpenApiDocumentsDirectory&amp;gt;&lt;/span&gt;$(MSBuildProjectDirectory)&lt;span class="nt"&gt;&amp;lt;/OpenApiDocumentsDirectory&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;OpenApiGenerateDocuments&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/OpenApiGenerateDocuments&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Execute o build do seu projeto para que seja gerado o arquivo .json contendo as especificações das APIs:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Crie um arquivo .spectral.yml com o conteúdo abaixo:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;spectral:oas"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Depois de tudo configurado e o arquivo &lt;strong&gt;.json&lt;/strong&gt; com as especificações OpenAPI também gerado, você já pode executar o Linter contra suas especificações:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;spectral lint &lt;span class="o"&gt;[&lt;/span&gt;NOME_DO_SEU_ARQUIVO].json&lt;br&gt;
...

&lt;p&gt;The output will show any issues with the OpenAPI document.&lt;/p&gt;

&lt;p&gt;&lt;span class="sb"&gt;```&lt;/span&gt;output&lt;br&gt;
1:1  warning  oas3-api-servers        OpenAPI &lt;span class="s2"&gt;"servers"&lt;/span&gt; must be present and non-empty array.&lt;br&gt;
3:10  warning  info-contact           Info object must have &lt;span class="s2"&gt;"contact"&lt;/span&gt; object.                        info&lt;br&gt;
3:10  warning  info-description       Info &lt;span class="s2"&gt;"description"&lt;/span&gt; must be present and non-empty string.       info&lt;br&gt;
9:13  warning  operation-description  Operation &lt;span class="s2"&gt;"description"&lt;/span&gt; must be present and non-empty string.  paths./.get&lt;br&gt;
9:13  warning  operation-operationId  Operation must have &lt;span class="s2"&gt;"operationId"&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;                             paths./.get&lt;/p&gt;

&lt;p&gt;✖ 5 problems &lt;span class="o"&gt;(&lt;/span&gt;0 errors, 5 warnings, 0 infos, 0 hints&lt;span class="o"&gt;)&lt;/span&gt;&lt;br&gt;
&lt;/p&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Conclusão 💭&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Em conclusão, o Scalar surge como uma ferramenta poderosa e intuitiva para a documentação de APIs usando a especificação OpenAPI. Com uma interface moderna, opções de exemplos de uso das APIs em diversas linguagens e plataformas, e uma integração eficiente com a especificação OpenAPI, o Scalar tem a capacidade de melhorar significativamente a experiência de documentação de APIs. &lt;/p&gt;

&lt;p&gt;Além disso, a integração com o Spectral, um linter de documentos OpenAPI de código aberto, possibilita a verificação da qualidade dos documentos OpenAPI gerados, assegurando uma documentação mais precisa e de qualidade superior. Portanto, o Scalar se apresenta como uma excelente alternativa ao Swagger para documentação OpenAPI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://scalar.com/" rel="noopener noreferrer"&gt;Scalar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/scalar/scalar/blob/main/packages/scalar.aspnetcore/README.md" rel="noopener noreferrer"&gt;Scalar for AspNet Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/aspnetcore-openapi?view=aspnetcore-9.0&amp;amp;tabs=netcore-cli#using-scalar-for-interactive-api-documentation" rel="noopener noreferrer"&gt;Microsoft.AspNetCore.OpenApi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>openapi</category>
      <category>apifirst</category>
      <category>swagger</category>
    </item>
    <item>
      <title>Arquitetura Event-Driven usando AsyncAPI na prática</title>
      <dc:creator>José Roberto Araújo</dc:creator>
      <pubDate>Mon, 20 May 2024 17:19:54 +0000</pubDate>
      <link>https://dev.to/emergingcode/arquitetura-event-driven-usando-asyncapi-na-pratica-dfo</link>
      <guid>https://dev.to/emergingcode/arquitetura-event-driven-usando-asyncapi-na-pratica-dfo</guid>
      <description>&lt;p&gt;No mundo atual, acelerado e interconectado, os dados se tornaram a força vital das empresas. Como resultado, a necessidade de uma gestão e integração de dados eficazes nunca foi tão grande. É aqui que a Arquitetura Orientada a Eventos (EDA) e a AsyncAPI entram em ação.&lt;/p&gt;

&lt;p&gt;EDA é um estilo arquitetural que enfatiza a o funcionamento assíncrono de sistemas distribuídos, reagindo a eventos. Ele permite o processamento de dados em tempo real e ajuda sistemas a se tornarem mais responsívos e ágeis. No entanto, gerir e governar a complexidade desse estilo de arquitetura pode se tornar um grande um desafio. É aqui que entra a &lt;strong&gt;AsyncAPI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AsyncAPI&lt;/strong&gt; é uma padrão de especificação, de código aberto, que descreve APIs orientadas a eventos. Ele fornece uma maneira padronizada de documentar e comunicar a estrutura e o comportamento de sistemas orientados a eventos. Ao adotar o uso do padrão AsyncAPI, as empresas ganham melhorias sobre a visibilidade dos contratos de mensagens, produtores e consumidores, melhora a governança sobre os dados que estão trafegando dentro da plataforma e aumenta a capacidade de identificação de impactos  sobre mudanças.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nesse post vou usar uma aplicação fictícia de reservar de quartos de hotel, afim de trazer um cenário mais prático e facilitar o entendimento de como aplicar o AsyncAPI em projetos no seu dia a dia.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Caso de uso 📝
&lt;/h2&gt;

&lt;p&gt;Em um sistema de reserva de quartos de hotel, quando um cliente efetua a reserva de um quarto no hotel, esse espaço precisa ser atualizado em toda a plataforma, indicando que a quantidade desse tipo de opção precisa ser decrementada ou não existe mais essa opção disponível para reserva, dada a data selecionada pelo cliente da aplicação.&lt;/p&gt;

&lt;p&gt;Imagine que você está desenhando uma solução de comunicação assíncrona para atender ao seguinte caso de uso: &lt;strong&gt;Atualizar o sistema quando um quarto for reservado&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Perceba que para realizar a implementação desse requisito será necessário envolver 3 áreas distintas dentro da plataforma, as quais detém a propriedade de 3 microsserviços diferentes: &lt;strong&gt;Reserva, Administração Hotel e Pesquisa.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quando o serviço de &lt;strong&gt;Reservas&lt;/strong&gt; recebe a requisição para confirmar a reserva, é então publicada uma mensagem (&lt;em&gt;neste caso um evento&lt;/em&gt;) do tipo &lt;strong&gt;&lt;em&gt;ReservaQuartoConfirmada&lt;/em&gt;&lt;/strong&gt;, o serviço de &lt;strong&gt;Administração Hotel&lt;/strong&gt; reage ao evento que foi publicado e atualiza as informações do quarto em seu sub-domínio, o que faz, por sua vez, provocar a publicação de uma outra mensagem diferente, informando que o quarto X foi atualizado, o que por sua vez vai acionar o serviço de &lt;strong&gt;Pesquisas&lt;/strong&gt; que tem a responsabilidade de atualizar a sua fonte de dados, indicando ou a diminuição da quantidade de quartos Xs disponíveis ou remover ele da lista de pesquisa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3twcruzwpt7f7mgsivmo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3twcruzwpt7f7mgsivmo.png" alt="Diagrama da solução EDA" width="800" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Analisando o cenário cima, percebe-se que uma simples ação de reservar um quarto no hotel, vai acionar vários serviços diferentes, responsáveis por atualizar seus respectivos sub-domínios, reagindo à um evento específico dentro da plataforma.&lt;/p&gt;

&lt;h2&gt;
  
  
  O problema ⚠️
&lt;/h2&gt;

&lt;p&gt;Após ter desenhado, apresentado e validado o design acima, já temos em mãos o desenho da solução pronto para seguir a diante. Certo!?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Não tão rápido assim, como você pensa! 🙂&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Em arquitetura de software não devemos, simplesmente, ter um desenho de solução em mãos e seguir para a implementação, antes de verificarmos outros estágios e passos, que nos guiarão durante a fase mais divertida para todos nós desenvolvedores: Realização da solução através de código. 💪🏻&lt;/p&gt;

&lt;p&gt;Analisando o contexto da solução, fica fácil percerber que a existência de 3 serviços distintos, provavelmente, também vai nos conduzir para uma tipologia de times onde normalmente temos 3 times diferentes, responsáveis por atuar com cada um desses serviços em separado.&lt;/p&gt;

&lt;p&gt;Microsserviços está diretamente relacionado com a parte &lt;strong&gt;estratégica do Domain-Driven Design&lt;/strong&gt;. Contextos Delimitados (Bounded Contexts) são conceitos fundamentais do DDD, dando essencial suporte para tomadas de decisões sobre as fronteiras de cada um dos serviços, e isso também define quais informações são publicadas de um sub-dominio para o meio externo, seja por meio de APIs internas ou seja, &lt;strong&gt;no nosso caso aqui desse post&lt;/strong&gt;, por meio de mensagem em plataformas de mensageria.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Se quiser saber mais sobre como modelar aplicações usando o DDD de forma estratégica, reserve um espaço na sua agenda para ler essa série de artigos &lt;strong&gt;&lt;a href="https://dev.to/jraraujo/series/26371"&gt;aqui&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Na solução proposta no diagrama acima, temos 2 tipos diferentes de mensagens: &lt;strong&gt;ReservaQuartoConfirmada&lt;/strong&gt; e &lt;strong&gt;QuartoAtualizado&lt;/strong&gt;. O contrato dessas mensagens precisa estar consistente e coerente para que ambos os times possa se comunicar de forma eficaz e efetiva, sem ter surpresas por uma eventual mudança, sem haver comunicação entre os times.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mas como se alcança algo tão organizado quanto o que se tem usando OpenAPI?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Um processo adequado deve estar implementado para descrever os diferentes componentes de um sistema orientado a eventos e suas interações.&lt;/p&gt;

&lt;p&gt;A especificação &lt;a href="https://www.asyncapi.com/en"&gt;AsyncAPI&lt;/a&gt; entra em ação neste ponto.&lt;/p&gt;

&lt;h2&gt;
  
  
  AsyncAPI specification FTW 🏆
&lt;/h2&gt;

&lt;p&gt;Abaixo está uma citação oficial do site AsynAPI, onde eles definem o que é e para que serve essa especificação:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AsyncAPI is an open-source initiative that seeks to improve the current state of Event-Driven Architectures (EDA). Our long-term goal is to make working with EDAs as easy as working with REST APIs. That goes from documentation to code generation, from discovery to event management, and beyond.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.asyncapi.com/docs"&gt;AsyncAPI official site&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O padrão AsyncAPI tomou como base muitas das definições e conjunto de dados, presentes dentro da especificação &lt;a href="https://swagger.io/specification/"&gt;OpenAPI&lt;/a&gt;. Dessa forma, a sua curva de aprendizado será muito baixa. Atualmente a versão mais recente do &lt;a href="https://www.asyncapi.com/docs/reference/specification/v3.0.0"&gt;AsyncAPI é a 3.0&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentanto a solução arquitetural
&lt;/h2&gt;

&lt;p&gt;Vamos começar a documentação da solução arquitetural, usando as especificações do AsyncAPI 3.0. O objetivo desse processo é criar especificações dos contratos das mensagens e compartilhar essa informação de forma global dentro da empresa. Dessa forma, os times terão confiança em iniciar o processo de implementação, validação, e o mais importante, ter a documentação toda documentada.&lt;/p&gt;

&lt;p&gt;Mais a frente neste artigo você vai ter contato com arquivos AsyncAPI já documentados. A especificação do padrão busca &lt;strong&gt;definir e anotar os diferentes componentes envolvidos dentro de uma arquitetura orientada a eventos&lt;/strong&gt;. Os formatos dos arquivos AsyncAPI pode ser construídos usando JSON ou Yaml. Eu vou usar o tipo Yaml neste artigo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentando os componentes
&lt;/h3&gt;

&lt;p&gt;Um dos grandes desafios de uma arquitetura orientada a eventos é identificar, além dos contratos das mensagens, quem são os serviços produtores de mensagens e quais são os consumidores dessa mensagens.&lt;/p&gt;

&lt;p&gt;Na especificação AsynAPI esses componentes arquiteturais, chamados &lt;em&gt;Serviços&lt;/em&gt;, são conhecidos como &lt;strong&gt;Aplicações,&lt;/strong&gt; conforme está na citação abaixo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;An application is any kind of computer program or a group of them. It MUST be a &lt;/em&gt;&lt;em&gt;&lt;a href="https://www.asyncapi.com/docs/specifications/2.0.0#definitionsProducer"&gt;producer&lt;/a&gt;&lt;/em&gt;&lt;em&gt;, a &lt;/em&gt;&lt;em&gt;&lt;a href="https://www.asyncapi.com/docs/specifications/2.0.0#definitionsConsumer"&gt;consumer&lt;/a&gt;&lt;/em&gt;&lt;em&gt; or both. An application MAY be a microservice, IoT device (sensor), mainframe process, etc. An application MAY be written in any number of different programming languages as long as they support the selected &lt;/em&gt;&lt;em&gt;&lt;a href="https://www.asyncapi.com/docs/specifications/2.0.0#definitionsProtocol"&gt;protocol&lt;/a&gt;&lt;/em&gt;&lt;em&gt;. An application MUST also use a protocol supported by the server in order to connect and exchange &lt;/em&gt;&lt;em&gt;&lt;a href="https://www.asyncapi.com/docs/specifications/2.0.0#definitionsMessage"&gt;messages&lt;/a&gt;&lt;/em&gt;*.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;— &lt;a href="https://www.asyncapi.com/blog/understanding-asyncapis"&gt;Fonte oficial&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agora é hora de por a mão na massa 😃&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentando o serviço de Reservas 🏗️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Documentação do serviço de Reservas:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;asyncapi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.0.0&lt;/span&gt;
&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Serviço de Reservas&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.0.0&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
    &lt;span class="s"&gt;A API de reservas permite realizar e gerenciar as reservas dos quartos de um hotel.&lt;/span&gt;
    &lt;span class="s"&gt;### Veja as funcionalidades desse serviço:&lt;/span&gt;

    &lt;span class="s"&gt;* Reservar um quarto 🌃  &lt;/span&gt;
    &lt;span class="s"&gt;* Confirmar a reserva de um quarto 😎&lt;/span&gt;
    &lt;span class="s"&gt;* Gerir as reservas dos quartos 📈&lt;/span&gt;
  &lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache &lt;/span&gt;&lt;span class="m"&gt;2.0&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://www.apache.org/licenses/LICENSE-2.0&lt;/span&gt;
&lt;span class="na"&gt;defaultContentType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;kafka-cluster&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prod.kafkacluster.org:28092&lt;/span&gt;
    &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kafka&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Cluster Kafka de produção&lt;/span&gt;
&lt;span class="na"&gt;channels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reservasdequartos.1.0.event.{roomId}.reservaQuarto.confirmada&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/messages/reservaQuartoConfirmada'&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Tópico responsável por mensagens de reservas confirmadas.&lt;/span&gt;
    &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;roomId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/parameters/roomId'&lt;/span&gt;
&lt;span class="na"&gt;operations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;confirmarReservaQuarto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;receive&lt;/span&gt;
    &lt;span class="na"&gt;channel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/channels/reservaQuartoConfirmada'&lt;/span&gt;
    &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
      &lt;span class="s"&gt;Ação utilizada para realizar a confirmação da reserva de um quarto.&lt;/span&gt;
    &lt;span class="na"&gt;traits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/operationTraits/kafka'&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/channels/reservaQuartoConfirmada/messages/reservaQuartoConfirmada'&lt;/span&gt;
&lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reservaQuartoConfirmada&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Reserva do quarto confirmada&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
        &lt;span class="s"&gt;Inform about environmental lighting conditions of a particular&lt;/span&gt;
        &lt;span class="s"&gt;streetlight.&lt;/span&gt;
      &lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
      &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/schemas/reservaQuartoConfirmada'&lt;/span&gt;
  &lt;span class="na"&gt;schemas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;quartoId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;entrada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date-time&lt;/span&gt;
        &lt;span class="na"&gt;saida&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date-time&lt;/span&gt;
        &lt;span class="na"&gt;nomeHospede&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;enviadaEm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/schemas/enviadoEm'&lt;/span&gt;
    &lt;span class="na"&gt;enviadoEm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
      &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date-time&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Date and time when the message was sent.&lt;/span&gt;
  &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;roomId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Identificador do quarto.&lt;/span&gt;
  &lt;span class="na"&gt;operationTraits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;kafka&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;kafka&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;enum&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app-reservas&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A primeira linha da especificação começa com o tipo de documento, asyncapi, e a versão (3.0.0). Esta linha não precisa ser a primeira, mas é uma prática recomendada.&lt;/p&gt;

&lt;p&gt;O objeto &lt;strong&gt;info&lt;/strong&gt; contém as informações mínimas necessárias sobre o aplicativo. Ele contém o título, que é um nome da aplicação (serviço) e sua versão. Embora não seja obrigatório, é altamente recomendável alterar a versão sempre que fizer alterações no serviço.&lt;/p&gt;

&lt;h3&gt;
  
  
  Seção dedicada a especificar os servidores
&lt;/h3&gt;

&lt;p&gt;A solução apresentada funciona com base em brokers de mensagens, ou servidores de mensagens. Isso obriga que durante a documentação, você identifique e documente qual ou quais servidores de mensagens estão sendo usados pela aplicação (serviço).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;kafka-cluster&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prod.kafkacluster.org:28092&lt;/span&gt;
    &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kafka&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Cluster Kafka de produção&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usando essa seção do documento, você pode documentar outros servidores de mensagens. Mais detalhes veja na &lt;a href="https://www.asyncapi.com/docs/tutorials/kafka#define-asyncapi-version-api-information-and-server"&gt;documentação oficial&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentando Channels, operations e messages
&lt;/h3&gt;

&lt;p&gt;Fazendo uma tradução direta sobre os termos do título acima, os &lt;strong&gt;channels&lt;/strong&gt; são tópicos ou filas, onde serão armazenadas as mensagens publicadas. As &lt;strong&gt;operations&lt;/strong&gt; são as operações que a aplicação (&lt;em&gt;serviço&lt;/em&gt;) vai executar dentro do seu próprio contexto, podendo ser de envio (&lt;strong&gt;SEND&lt;/strong&gt;) ou de recebimento (&lt;strong&gt;RECEIVE&lt;/strong&gt;). Dessa forma, a especificação dá visibilidade sobre onde e como a aplicação vai se conectar e publicar o consumir mensagens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;channels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reservasdequartos.1.0.event.{roomId}.reservaQuarto.confirmada&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/messages/reservaQuartoConfirmada'&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Tópico responsável por mensagens de reservas confirmadas.&lt;/span&gt;
    &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;roomId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/parameters/roomId'&lt;/span&gt;
&lt;span class="na"&gt;operations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;confirmarReservaQuarto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;send&lt;/span&gt;
    &lt;span class="na"&gt;channel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/channels/reservaQuartoConfirmada'&lt;/span&gt;
    &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
      &lt;span class="s"&gt;Ação utilizada para realizar a confirmação da reserva de um quarto.&lt;/span&gt;
    &lt;span class="na"&gt;traits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/operationTraits/kafka'&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/channels/reservaQuartoConfirmada/messages/reservaQuartoConfirmada'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada operação é mapeada para um tópico ou fila, informando qual é a ação específica que vai ser executada &lt;strong&gt;SEND&lt;/strong&gt; ou &lt;strong&gt;RECEIVE&lt;/strong&gt;, além de especificar qual é o schema da mensagem que será ou enviada ou recebida desse tópico ou fila.&lt;/p&gt;

&lt;p&gt;O contrato da mensagem é o que estamos buscando documentar, afim de dar visibilidade sobre os dados que estão trafegando de um serviço para o outro, dentro de uma arquitetura distribuída.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentando mensagens e o payload
&lt;/h3&gt;

&lt;p&gt;No diagrama da solução há serviços que apenas publica mensagens (&lt;em&gt;eventos&lt;/em&gt;) e outros que publicam e consomem mensagens de eventos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reservaQuartoConfirmada&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Reserva do quarto confirmada&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
        &lt;span class="s"&gt;Inform about environmental lighting conditions of a particular&lt;/span&gt;
        &lt;span class="s"&gt;streetlight.&lt;/span&gt;
      &lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
      &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/schemas/reservaQuartoConfirmada'&lt;/span&gt;
  &lt;span class="na"&gt;schemas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;quartoId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;entrada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date-time&lt;/span&gt;
        &lt;span class="na"&gt;saida&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date-time&lt;/span&gt;
        &lt;span class="na"&gt;nomeHospede&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;enviadaEm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/schemas/enviadoEm'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O trecho documentado acima, você encontra a documentação do payload, ou seja, do schema (estrutura) da mensagem de evento que será tanto publicada quanto consumida em um dado momento do tempo. As definições do esquema de uma mensagem usando &lt;strong&gt;AsyncAPI&lt;/strong&gt;, são 100% compatíveis com o esquema do tipo JSON.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentando o serviço Administração Hotel
&lt;/h3&gt;

&lt;p&gt;A documentação do serviço de administração de hotel será similar a documentação do serviço anterior, isso porque a mensagem que é publicada pelo serviço de reservas será a mesma mensagem &lt;strong&gt;consumida&lt;/strong&gt; pelo serviço de administração.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;asyncapi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.0.0&lt;/span&gt;
&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Serviço de administração do hotel&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.0.0&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
    &lt;span class="s"&gt;A API de administração do hotel permite realizar e gerir todos os dados relativos ao hotel e os respectivos quartos.&lt;/span&gt;
    &lt;span class="s"&gt;### Veja as funcionalidades desse serviço:&lt;/span&gt;

    &lt;span class="s"&gt;* Registrar quartos 🛏️&lt;/span&gt;
    &lt;span class="s"&gt;* Gerir dados do hotel 📇&lt;/span&gt;
    &lt;span class="s"&gt;* Gerir dados dos quartos 📈&lt;/span&gt;
  &lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache &lt;/span&gt;&lt;span class="m"&gt;2.0&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://www.apache.org/licenses/LICENSE-2.0&lt;/span&gt;
&lt;span class="na"&gt;defaultContentType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
&lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;kafka-cluster&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prod.kafkacluster.org:28092&lt;/span&gt;
    &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kafka&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Cluster Kafka de produção&lt;/span&gt;
&lt;span class="na"&gt;channels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reservasdequartos.1.0.event.{roomId}.reservaQuarto.confirmada&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/messages/reservaQuartoConfirmada'&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Tópico responsável por mensagens de reservas confirmadas.&lt;/span&gt;
    &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;roomId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/parameters/roomId'&lt;/span&gt;
&lt;span class="na"&gt;operations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;confirmarReservaQuarto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;receive&lt;/span&gt;
    &lt;span class="na"&gt;channel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/channels/reservaQuartoConfirmada'&lt;/span&gt;
    &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
      &lt;span class="s"&gt;Ação utilizada para realizar a confirmação da reserva de um quarto.&lt;/span&gt;
    &lt;span class="na"&gt;traits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/operationTraits/kafka'&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/channels/reservaQuartoConfirmada/messages/reservaQuartoConfirmada'&lt;/span&gt;
&lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;reservaQuartoConfirmada&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Reserva do quarto confirmada&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;-&lt;/span&gt;
        &lt;span class="s"&gt;Inform about environmental lighting conditions of a particular&lt;/span&gt;
        &lt;span class="s"&gt;streetlight.&lt;/span&gt;
      &lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
      &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/schemas/reservaQuartoConfirmada'&lt;/span&gt;
  &lt;span class="na"&gt;schemas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;reservaQuartoConfirmada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;quartoId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;entrada&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date-time&lt;/span&gt;
        &lt;span class="na"&gt;saida&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date-time&lt;/span&gt;
        &lt;span class="na"&gt;nomeHospede&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;enviadaEm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;$ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;#/components/schemas/enviadoEm'&lt;/span&gt;
    &lt;span class="na"&gt;enviadoEm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
      &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;date-time&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Date and time when the message was sent.&lt;/span&gt;
  &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;roomId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Identificador do quarto.&lt;/span&gt;
  &lt;span class="na"&gt;operationTraits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;kafka&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;kafka&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;enum&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app-administracao-hotel&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Através dessas duas documentações, somos possíveis de descobrir quem são os produtores, consumidores e principalmente quais são os dados que ambos os serviços estão consumindo.&lt;/p&gt;

&lt;p&gt;A imagem abaixo ilustra o resultado da documentação usando AsyncApi Studio:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6dsav2h2nvyxjwfwazu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6dsav2h2nvyxjwfwazu.png" alt="Image description" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡Se você quiser se divertir um pouco, pode acessar o &lt;a href="https://studio.asyncapi.com/"&gt;AsyncAPI Studio&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principais conclusões
&lt;/h2&gt;

&lt;p&gt;Adotar o padrão de especificação AsyncAPI em sistemas que aplicação uma arquitetura orientada a eventos (&lt;strong&gt;&lt;em&gt;EDA - Event-Driven Architecture&lt;/em&gt;&lt;/strong&gt;), aumenta a consistência, eficiência e a governança entre diferentes times de desenvolvimento.&lt;/p&gt;

&lt;p&gt;O ecossistema de ferramentas do AsyncAPI ajuda a acelerar o desenvolvimento de aplicativos, automatizando tarefas tediosas, mas necessárias, como geração de código, geração de documentação, validadores, etc.&lt;/p&gt;

&lt;p&gt;A comunidade AsyncAPI está crescendo muito. Sua contribuição para a comunidade será valiosa em termos de criação de melhores aplicativos orientados a eventos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.asyncapi.com/en"&gt;https://www.asyncapi.com/en&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://studio.asyncapi.com/"&gt;https://studio.asyncapi.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>asyncapi</category>
      <category>eventdriven</category>
      <category>arquiteturasoftware</category>
      <category>sistemasdistribuidos</category>
    </item>
    <item>
      <title>Domain-Driven Design Estratégico: Extraindo Sub-domínios com EventStorming</title>
      <dc:creator>José Roberto Araújo</dc:creator>
      <pubDate>Tue, 05 Mar 2024 10:18:11 +0000</pubDate>
      <link>https://dev.to/emergingcode/domain-driven-design-de-forma-estrategica-extraindo-sub-dominios-com-eventstorming-m7k</link>
      <guid>https://dev.to/emergingcode/domain-driven-design-de-forma-estrategica-extraindo-sub-dominios-com-eventstorming-m7k</guid>
      <description>&lt;p&gt;Os últimos artigos publicados, foram determinantes para a formação da base necessária sobre a compreensão sobre o que é, o como devemos lidar e qual importância tem a parte &lt;strong&gt;Estratégica&lt;/strong&gt; do Domain-Driven Design.&lt;/p&gt;

&lt;p&gt;Foram apresentadas algumas técnicas auxiliares que ajudarão a aumentar a compreensão sobre domínios de negócio, e para além disso também melhorar a identificação e compreensão dos requisitos desejados para um produto de software.&lt;/p&gt;

&lt;p&gt;Agora, já estamos quase prontos para seguir adiante nessa jornada, aplicando as práticas estratégicas do &lt;strong&gt;Domain-Driven Design&lt;/strong&gt;, vou te fornecer mais ferramentas que te capacitarão a desdobrar o domínio de um sistema proposto: &lt;strong&gt;FoodDelivery,&lt;/strong&gt; identificando, neste artigo, os &lt;strong&gt;sub-domínios&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;⚠️ &lt;em&gt;Caso você caiu nesse artigo e ainda não entende a definição de sub-domínio, te convido a dar uma pausa nessa leitura e ler o &lt;a href="https://dev.to/emergingcode/domain-driven-design-de-forma-estrategica-destilando-o-dominio-22ej"&gt;post anterior&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Vamos refinar um pouco mais alguns conceitos básicos e consolidá-los no nosso conhecimento.&lt;/p&gt;

&lt;p&gt;O tema sub-domínios leva muitas pessoas ao entendimento de que cada unidade de negócio, dentro de uma empresa, pode ser considerada como um sub-domínio, per-si. Isso é um equívoco comum de acontecer.&lt;/p&gt;

&lt;p&gt;Vamos usar o exemplo de um sistema PetClinic. Dentro desse sistema, vão existir várias áreas de negócio, com suas respectivas regras, modelos, pessoas responsáveis, e interações e comunicações entre as outras partes do sistema. Tais áreas podem ser: &lt;strong&gt;Gestão de pacientes, agendamento de consultas, registros veterinários de um pet&lt;/strong&gt;. Olhando para esse sistema, fatalmente o entendimento mais comum seria: &lt;em&gt;Vamos assumir que cada área dessas vai ser nosso sub-domínio&lt;/em&gt; 🤔.&lt;/p&gt;

&lt;p&gt;💭 &lt;em&gt;Nem sempre tudo aquilo que se observa com frequência é a verdade absoluta das coisas.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tudo que se vê não é! - &lt;strong&gt;Lulu Santos.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Dando continuidade ao exemplo acima, peço que você remova o véu de tudo o que você já viu de projetos de código, supostamente, aplicando técnicas do DDD, e me acompanha cuidadosamente nessa explicação sobre &lt;em&gt;Sub-domínios e Domínios de negócio&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Analisando o fato já externalizado acima, é possível perceber que teríamos, supostamente, 3 sub-domínios distintos: &lt;strong&gt;Gestão de pacientes, agendamento de consultas, registros clínicos de um pet&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Vamos levantar algumas provocações sobre as informações que já temos em mãos: Poderia a gestão de pacientes e agendamento de pacientes, pertencerem ao mesmo departamento ou unidade de negócio? &lt;strong&gt;Claro que sim&lt;/strong&gt;! Outra agora mais intrigante: &lt;strong&gt;Parte&lt;/strong&gt; da gestão de pacientes, poderia pertencer a mais de um departamento? Sim ✅. Essa é a razão pela qual, ao modelar o domínio principal de uma empresa, não se deve ficar apegado aos departamentos que a empresa possui, apesar deles te ajudarem a ter uma visão geral de como a empresa está dividida.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2m1v5xfvoeh6s0tg0rgk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2m1v5xfvoeh6s0tg0rgk.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos imaginar uma plataforma online de streams de filmes, similar a Netflix. Nessa plataforma haverão separações de áreas (&lt;em&gt;sub-domínios&lt;/em&gt;) distintas por funcionalidade, onde cada uma delas vai ter suas próprias: &lt;em&gt;Regras, fluxos, linguagem e implementação&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Catalogo de filmes &lt;strong&gt;sub-domínio&lt;/strong&gt;: Esse sub-domínio tem a responsabilidade de fazer a gestão sobre o catalogo de filmes e séries:

&lt;ul&gt;
&lt;li&gt;Registrar um filme/série&lt;/li&gt;
&lt;li&gt;Atualizar informações de um filme&lt;/li&gt;
&lt;li&gt;Categorizar o contéudo (&lt;em&gt;filmes de suspense, comédia, ação&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Player &lt;strong&gt;sub-domínio&lt;/strong&gt;: Esse sub-domínio vai gerir COMO é consumido o conteúdo do catálogo e vai gerir a execução desse conteúdo para o usuário:

&lt;ul&gt;
&lt;li&gt;Play (tocar) o conteúdo&lt;/li&gt;
&lt;li&gt;Pause (pausar)  o conteúdo&lt;/li&gt;
&lt;li&gt;Tracking time (gestor de tempo) do tempo assistido.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Gestão da conta do usuário &lt;strong&gt;sub-domínio&lt;/strong&gt;: Nesse sub-domínio será onde acontecerá a gestão de conta de cada usuário da platafroma

&lt;ul&gt;
&lt;li&gt;Payment method (forma de pagamento)&lt;/li&gt;
&lt;li&gt;Quality of Service (Qualidade do serviço: HD, 4K)&lt;/li&gt;
&lt;li&gt;Address and Contacts (gestão de contatos e endereço)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ao definir os sub-domínios em um sistema, abre-se espaço para que as pessoas responsáveis pela construção do sistema, tenham uma visão sobre cada uma dessas áreas, e assim possam manter o foco em suas regras e complexidades específicas de cada uma dessas delimitações de unidades. Essa abordagem de descoberta e extração de áreas específicas, permite melhorar a clareza na comunicação entre os times e permite entender até onde cada um pode ir, para além de visualizar os impactos que cada alteração pode implicar uns aos outros.&lt;/p&gt;

&lt;p&gt;Existe uma compreensão bastante importante para você ter em mente: &lt;em&gt;nem tudo é da forma como se vê&lt;/em&gt;. É preciso explorar um pouco mais as necessidades do contexto e perceber a responsabilidade que ele tem dentro da empresa, pois vão existir momentos em que o que hoje você vê como sendo um sub-domínio, pode se tornar um domínio de negócio, contendo outros sub-domínios. A modelagem abaixo ilustra bem essa visão:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jmxjw52w8ipkgsgqht5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jmxjw52w8ipkgsgqht5.png" alt="Image description" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🔎 Observando a modelagem da esquerda, é possível perceber que para a plataforma de &lt;strong&gt;&lt;em&gt;FoodDelivery&lt;/em&gt;&lt;/strong&gt;, o negócio não demanda a necessidade de o sub-domínio &lt;strong&gt;&lt;em&gt;Order&lt;/em&gt;&lt;/strong&gt; se tornar um domínio de negócio. Já no diagrama da direita, o planejamento da empresa entende que &lt;strong&gt;&lt;em&gt;Order&lt;/em&gt;&lt;/strong&gt; terá a responsabilidade de gerir todo o ciclo de realização (&lt;strong&gt;&lt;em&gt;fullfilment&lt;/em&gt;&lt;/strong&gt;) de um pedido (&lt;strong&gt;&lt;em&gt;order&lt;/em&gt;&lt;/strong&gt;), transformando a área &lt;strong&gt;Order&lt;/strong&gt; em domínio core, e que nesse caso está contendo outros 3 sub-domínios.&lt;/p&gt;




&lt;p&gt;Agora eu acredito que tenha ficado claro para você, o que é um Domínio e o que representa um sub-domínio dentro da modelagem estratégica do DDD. &lt;/p&gt;

&lt;p&gt;❗&lt;em&gt;Caso tenha ficado alguma dúvida, deixe suas dúvidas nos comentários.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Mas como eu posso aplicar essas técnicas para descobrir e extrair esses sub-domínios no meu projeto?&lt;/p&gt;

&lt;p&gt;Para nos ajudar durante a jornada de exploração e identificação de sub-domínios, existem algumas técnicas que podem ser utilizadas, abaixo eu cito 2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event Storming&lt;/li&gt;
&lt;li&gt;Domain Storytelling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em projetos que participo, particularmente utilizo o &lt;strong&gt;&lt;em&gt;Event Storming&lt;/em&gt;&lt;/strong&gt;, mas o Domain Storytelling se mostra uma excelente técnica para explorar e dar visibilidade aos sub-domínios de um sistema.&lt;/p&gt;

&lt;p&gt;Agora vou começar as explorar os diversos comportamentos do sistema, usando &lt;strong&gt;Event Storming&lt;/strong&gt;. Existe muito conteúdo sobre esse tema. &lt;a href="https://github.com/mariuszgil/awesome-eventstorming"&gt;Compartilho esse link&lt;/a&gt; contendo muitas fontes de estudos sobre o tema.&lt;/p&gt;




&lt;p&gt;Basicamente, o EventStorming te permite identificar alguns níveis de abstração:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visão geral (Big Picture)&lt;/li&gt;
&lt;li&gt;Modelagem de processos (Process modeling/Business Flows)&lt;/li&gt;
&lt;li&gt;Contextos delimitados (Bounded Contexts)&lt;/li&gt;
&lt;li&gt;Personas &amp;amp; Entidades&lt;/li&gt;
&lt;li&gt;Políticas (Policies/Rules)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cada uma desses pontos identidicados, vão colocar luz sobre aspectos da abstração em si, trazendo idéias e entendimentos valiosos, os quais nos permitirão concretizar a modelagem de um sistema.&lt;/p&gt;

&lt;h3&gt;
  
  
  Iniciando a jornada de descoberta
&lt;/h3&gt;

&lt;p&gt;Antes de iniciar o processo de descobertas, vamos entender rapidamente como &lt;strong&gt;EventStorming&lt;/strong&gt; define os tipos de cartões, o que cada cor representa para um ticket e como eles facilitam a identificação sobre as responsabilidades, durante todo o workshop. Na imagem abaixo você tem uma legenda:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faex6hgjpbunrog9b5upi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faex6hgjpbunrog9b5upi.png" alt="Image description" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cada cartão tem a sua responsabilidade e definição dentro do método &lt;strong&gt;EventStorming&lt;/strong&gt;. Abaixo estão descritas as definições de cada um:&lt;/p&gt;

&lt;h4&gt;
  
  
  Evento (Event)
&lt;/h4&gt;

&lt;p&gt;Eventos são reações à ações que aconteceram no passado. Usamos os verbos escritos no passado, indicando para o receptor do efeito dessa ação, que ela foi executada. Para modelar um processo de negócios, simplesmente organizamos os eventos da esquerda para a direita em uma sequência temporal.&lt;/p&gt;

&lt;h4&gt;
  
  
  Comando (Command)
&lt;/h4&gt;

&lt;p&gt;Um comando pode ser entendido como uma decisão, ação ou intenção de algo sobre alguma coisa. É a manifestação de interação com o sistema em questão. Comandos são críticos, pois eles representam a intenção de interação de um usuário ou de um outro sistema sobre algum processo. Pro exemplo, quando um usuário expressa a vontade de adicionar um pedido em um e-commerce, é esperado que essa ação seja escrita com o comando: &lt;strong&gt;RegistrarPedido&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ator/Persona (User)
&lt;/h4&gt;

&lt;p&gt;É o agente responsável por interagir com alguma ação dentro de um determinado fluxo de negócio, e também responsável por uma dada decisão. Por meio desse tipo de cartão que se torna possível identificar pessoas que vão interagir com o sistema ou parte de um fluxo.&lt;/p&gt;

&lt;h4&gt;
  
  
  Modelos de Leitura (Read Model)
&lt;/h4&gt;

&lt;p&gt;Nos permite consultar dados dentro do sistema. Consultamos porque queremos saber algo. Temos perguntas que o sistema pode nos responder, nos permitindo definir alguns limites dentro de uma consulta e retornando os itens que estão dentro dos limites que definimos. O uso dos dados retornados por um modelo de leitura, pode nos ajudar em um processo de tomada de decisão.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hotspot
&lt;/h4&gt;

&lt;p&gt;Em workshops dessa natureza, é absolutamente natural que alguns conflitos de interesses apareçam durante o mapeamento dos fluxos. &lt;em&gt;Não entenda isso como algo negativo, pois é um evento positivo dentro desse processo&lt;/em&gt;. Um conflito pode ser por uma informação incompleta, um entendimento mal explicado, ou seja, pode ser qualquer coisa que leve pessoas a não entrarem em concordância. Para gerir esse tipo de conflito, usamos o cartão do tipo &lt;strong&gt;Hotspot&lt;/strong&gt;, deixando registrado esses pontos de discordância, destacando que há questões que precisam ser resolvidas em um determinado momento durante o desenvolvimento do projeto de software.&lt;/p&gt;

&lt;h4&gt;
  
  
  Política (Policy)
&lt;/h4&gt;

&lt;p&gt;Uma política define regras que reagem aos eventos ou comandos que são emitidos em fluxos de negócio. Você pode pensar em uma política assim "&lt;em&gt;Sempre que X acontecer, precisamos fazer Y&lt;/em&gt;”, eventualmente terminando dentro do fluxo entre um Evento de Domínio e/ou um Comando/ação. É possível utilizar outra expressão, como: &lt;strong&gt;&lt;em&gt;Imediatamente à isso.&lt;/em&gt;&lt;/strong&gt; Pense no cenário onde um usuário acabou de resgistrar em uma plataforma. Então &lt;strong&gt;&lt;em&gt;Sempre que o usuário se registrar&lt;/em&gt;&lt;/strong&gt; ou &lt;strong&gt;&lt;em&gt;Imediatamente ao registro do usuário&lt;/em&gt;&lt;/strong&gt;, o sistema deve enviar um email de boas vindas.&lt;/p&gt;




&lt;p&gt;🎉 Agora é hora de começarmos a mergulhar em torno do processo de descoberta e mapeamento do domínio do &lt;strong&gt;FoodDelivery.&lt;/strong&gt; Durante o processo inicial de identificação dos eventos que podem, eventualmente, acontecer dentro de um sistema, cada participante tem a liberdade de poder identificar o evento que ele/a entender ser importante para adicionar ao quadro (físico ou online). A imagem abaixo, facilita perceber que, neste momento, não existe linha do tempo definida, ainda.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9ufww8vxck03hggnzsw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9ufww8vxck03hggnzsw.png" alt="Image description" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Analisando os tickets no quadro acima, você pode observar a disposição potenciais eventos que podem ocorrer dentro de um sistema de &lt;strong&gt;FoodDelivery&lt;/strong&gt;. Veja também que foram permitidos apontar vários tipos de eventos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Os &lt;strong&gt;relacionados ao negócio&lt;/strong&gt;: &lt;strong&gt;&lt;em&gt;Order Placed&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;E eventos relacionados coisas técnicas. Exemplo: &lt;strong&gt;&lt;em&gt;Cart requested payment API&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ainda que sejam cartões de eventos válidos, o nosso foco aqui é sobre os &lt;strong&gt;aspectos relacionados ao negócio&lt;/strong&gt;. Por isso, vamos removê-los desse quadro cima.&lt;/p&gt;

&lt;p&gt;Após a limpeza dos cartões que não traz relevância para essa análise, o seu quadro deve se parecer como o da imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdj0j05lzr2x4o96vxiz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdj0j05lzr2x4o96vxiz.png" alt="Image description" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que só temos tickets relacionados ao espaço de negócio, vamos agrupar os tickets com base em alguns critérios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identificar &lt;strong&gt;palavras&lt;/strong&gt; semelhantes: Tome cuidado ao analisar o contexto de cada uma delas, afim de classifica-las com base nesse entendimento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linha do tempo&lt;/strong&gt;: Analise os eventos que precisam acontecer antes de acontecer o próximo evento.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrzu9vx3y5vbh7abbmgt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrzu9vx3y5vbh7abbmgt.png" alt="Image description" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esse agrupamento de contextos permite destacar um esboço dos sub-domínios que esse tipo de sistema pode considerar para funcionar. Colocando os cartões em ordem cronológica, temos a seguinte visão:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71zynocvtuacucu7vfa7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71zynocvtuacucu7vfa7.png" alt="Image description" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao final desse trabalho inicial de descoberta e mapeamento de sub-domínios, esses são os contextos que temos para iniciar os trabalhos. Com a evolução do negócio e com a inclusão de novas funcionalidades, os fluxos tendem a mudar em um dado momento do tempo. Mantenha um snapshot (foto) desse esboço, para que você tenha condições de ir evoluindo esse mapeamento no futuro.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwu3i63usmpczfx8h746.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwu3i63usmpczfx8h746.png" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Ao final da leitura desse artigo, é fácil perceber que a aplicação das técnicas do Domain-Driven Design não se resumem à apenas programar &lt;em&gt;Entidades, Agregadores, Serviços de Domínio e entidades correlatas&lt;/em&gt;. Modelar um domínio de negócio, é uma tarefa essencial para a sobrevivência de qualquer sistema &lt;strong&gt;Line-of-Business&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Entender quais ferramentas e técnicas podem ser aplicadas para rodar essa fase inicial, será o seu divisor de águas entre ter um sistema com uma modelagem de negócio ajustada às necessidades da empresa ou simplesmente reproduzir modelos de repositórios do github.&lt;/p&gt;

&lt;p&gt;Não menos importante, também foi possível ter uma visão rápida sobre o que significa cada um dos cartões utilizados no método &lt;strong&gt;EventStorming&lt;/strong&gt;. Usando esse conhecimento, avançamos o inicio do brainstorming, levantando todas as possibilidades de potenciais eventos que poderiam ocorrer dentro desse tipo de sistema. Finalizando em um agrupamento contextualizado, começando a dar visibilidade sobre os esboços de sub-domínios.&lt;/p&gt;

&lt;p&gt;Agora é seguir para o próximo capítulo dessa série, onde iremos &lt;strong&gt;Refinar&lt;/strong&gt;, ainda mais, essa modelagem 👋🏻.&lt;/p&gt;

&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.eventstorming.com/"&gt;https://www.eventstorming.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://domainstorytelling.org/"&gt;https://domainstorytelling.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/hofstef/awesome-domain-storytelling"&gt;https://github.com/hofstef/awesome-domain-storytelling&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ddd</category>
      <category>domaindrivendesign</category>
      <category>business</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Domain-Driven Design Estratégico: Destilando o domínio</title>
      <dc:creator>José Roberto Araújo</dc:creator>
      <pubDate>Fri, 16 Feb 2024 12:42:24 +0000</pubDate>
      <link>https://dev.to/emergingcode/domain-driven-design-de-forma-estrategica-destilando-o-dominio-22ej</link>
      <guid>https://dev.to/emergingcode/domain-driven-design-de-forma-estrategica-destilando-o-dominio-22ej</guid>
      <description>&lt;p&gt;Somos contratados com a responsabilidade de colaborar com a construção de sistemas que estão inseridos dentro de um contexto de negócio, chamado: &lt;strong&gt;Domínio&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Operar em diferentes áreas ou nichos de negócio, comumente chamados de &lt;strong&gt;Domínio&lt;/strong&gt;, faz parte do trabalho de qualquer pessoa técnica imergida no desenvolvimento sistemas, independente se está atuando no backend, arquitetura, ou UI. Ter o entendimento do setor no qual se está inserido, é essencial para que qualquer pessoa possa, minimamente, compreender os fluxos das informações e processos.&lt;/p&gt;

&lt;p&gt;No &lt;a href="https://dev.to/emergingcode/domain-driven-design-de-forma-estrategica-o-inicio-1df2"&gt;primeiro artigo dessa série&lt;/a&gt;, foi explorada a importância da descoberta de sub-domínios dentro de um domínio e quais processos podem ser usados para ajudar a encontrar e entender o funcionamento do Business Flow (&lt;em&gt;Fluxo de Negócio&lt;/em&gt;) de um determinado setor do mercado, no qual você está trabalhando. &lt;/p&gt;

&lt;p&gt;Também, foram citados  exemplos de setores do mercado, tais com:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;E-Commerce&lt;/li&gt;
&lt;li&gt;Tributação&lt;/li&gt;
&lt;li&gt;Educação&lt;/li&gt;
&lt;li&gt;Logística&lt;/li&gt;
&lt;li&gt;Saúde&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cada sub-domínio identificado dentro de cada um dos setores (domínios) acima, são classificados de &lt;strong&gt;Arquétipos&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O que são &lt;strong&gt;Arquétipos&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Segundo a filosofia, arquétipos são uma espécie de especialização sobre alguma coisa, ou sobre algum comportamento, ou sobre alguma entidade.&lt;/p&gt;

&lt;p&gt;Através da perspectiva de Platão, temos o seguinte:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Apesar de ser tentador pensar nas Formas como entidades mentais (&lt;em&gt;ideias&lt;/em&gt;) que existem apenas em nossa mente, o filósofo insistiu que elas são independentes de quaisquer mentes (&lt;em&gt;atuais&lt;/em&gt;). &lt;strong&gt;As Ideias seriam coletivos no sentido de incorporarem as características fundamentais de uma coisa&lt;/strong&gt; (&lt;em&gt;qualidade universal&lt;/em&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Extrai-se dessa afirmação que devemos ter atenção ao contexto real de onde as coisas estão emergindo, sem o véu do achismo, compartilhando entendimento coletivo sobre como cada área dentro de um domínio funciona.&lt;/p&gt;




&lt;h1&gt;
  
  
  Entendendo conceitos essenciais
&lt;/h1&gt;

&lt;p&gt;Saber diferenciar o que é um &lt;em&gt;domínio&lt;/em&gt; de um &lt;em&gt;sub-domínio&lt;/em&gt;, é a chave para o sucesso nessa fase de modelagem estratégica, considerando que a compreensão desses conceitos essenciais vai ajudar não só na identificação de áreas de responsabilidades, como também na organização das topologias dos times e delimitação de fronteiras de responsabilidades e conhecimentos distribuídos dentro das diversas unidades de negócio em uma empresa.&lt;/p&gt;

&lt;p&gt;Existe uma grande confusão sobre o que é e como se deve trabalhar com domínios e sub-domínios. Além disso, é comum encontrar e ouvir colegas se referindo à sub-domínios como sendo domínios e vice-versa. - &lt;em&gt;Não se preocupa com isso, porque eu também já cometi esse erro. Por isso escrevi esse post para te ajudar a entender os conceitos de forma correta&lt;/em&gt; 🙂.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domínio
&lt;/h3&gt;

&lt;p&gt;Um &lt;strong&gt;domínio&lt;/strong&gt; refere-se a uma esfera de conhecimento, atividade ou interesse que é sujeita a modelagem. Também pode ser entendido como um setor de negócio.&lt;/p&gt;

&lt;p&gt;O domínio define o contexto para o qual um software está sendo desenvolvido e aplicado. Assim sendo,  um domínio é composto por conceitos, linguagens específicas, regras e processos que são relevantes para resolver os desafios apresentados por um determinado nicho de negócio.&lt;/p&gt;

&lt;p&gt;Como já citado, no inicio desse post, domínios pode ser qualquer setor de negócio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agricultura&lt;/li&gt;
&lt;li&gt;Saúde&lt;/li&gt;
&lt;li&gt;E-Commerce&lt;/li&gt;
&lt;li&gt;Logística&lt;/li&gt;
&lt;li&gt;Correios&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O que diferencia um domínio do outro? Bem, isso vai depender de como cada proprietário de empresas, atuantes em um negócio específico, deseja resolver os desafios impostos pelas leis, regras e processos dentro do domínio que ele escolheu trabalhar.&lt;/p&gt;

&lt;p&gt;No setor de Logística, por exemplo, existem vários desafios que podem ser enfrentados para gerir o tracking (acompanhamento) de encomendas e gestão de estoque.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sub-domínio
&lt;/h3&gt;

&lt;p&gt;Um "sub-domínio" é uma parte menor ou uma subdivisão do domínio principal. Ele pode representar uma área específica dentro do domínio maior ou um conjunto de conceitos especializados dentro do contexto desse sub-domínio.&lt;/p&gt;

&lt;p&gt;Sub-domínios são úteis para organizar a modelagem para esse contexto específico, quando o domínio principal é grande ou complexo demais para ser tratado como único. Cada sub-domínio pode ter suas próprias regras, terminologias e especializações de processos.&lt;/p&gt;

&lt;p&gt;Ainda podem existir casos em que um sub-domínio pode ganhar notoriedade entre os outros sub-domínios, tornando-se em um domínio propriamente dito, dentro de um domínio principal, tamanha a sua complexidade  acumulada, tornando necessário aplicar, novamente, técnicas de descoberta de sub-domínios desse, que antes, era um sub-domínio.&lt;/p&gt;




&lt;h1&gt;
  
  
  Entendendo o domínio: &lt;u&gt;Food Delivery&lt;/u&gt;
&lt;/h1&gt;

&lt;p&gt;Todos nós somos contratados para desenvolver sistemas que estão inseridos em um contexto de negócio muito específico, por mais know-how (conhecimento) que você possa ter nessa área, haverá sempre uma oportunidade para enfrentar desafios novos.&lt;/p&gt;

&lt;p&gt;Domain-Driven Design oferece ferramentas úteis e que nos dão o suporte necessário para trabalharmos os principais fundamentos da parte estratégica, criando modelagens que refletem a realidade de um setor de negócio, alinhando os contextos ao desenvolvimento do software que dará vida digital aos processos de uma empresa.&lt;/p&gt;

&lt;p&gt;FoodDelivery será o domínio que utilizaremos durante toda a série de posts, guiando você sobre as técnicas e ferramentas adequadas, te ajudando a compreender como lidar com domínios e sub-domínios, contribuindo melhorar a organização e comunicação entre as unidades de negócio em projetos de software de uma empresa. Esse será o Moto dessa série.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Até aqui foram apresentadas muitas teorias! Mas como podemos descobrir e extrair esses processos?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No primeiro artigo, mencionamos várias técnicas úteis para descobertas de processos e sub-domínios, como &lt;strong&gt;Event Storming&lt;/strong&gt; ou &lt;strong&gt;Domain Storytelling&lt;/strong&gt;. Realizando workshops com um grupo reduzido de pessoas especialistas nas áreas importantes a serem debatidas, trabalhando a idealização do funcionamento desses fluxos de negócio.&lt;/p&gt;

&lt;p&gt;Não se trata de nenhuma regra que te imponha chegar em uma organização propondo aplicar todas essas técnicas. Contudo, cedo ou tarde a aplicação dessas técnicas e ferramentas será não só útil, mas também necessária. Porém, inicialmente o que normalmente vai acontecer é que você será convidado para participar de rodadas de apresentações das necessidades de negócio da empresa. Algo similar ao diálogo simulado abaixo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Estamos com a necessidade de criar uma plataforma como serviço que seja usada para realizar pedidos de refeições online. Essa plataforma vai cobrir desde o cadastro de um restaurante como parceiro até a entrega dos pedidos.&lt;/p&gt;

&lt;p&gt;Também queremos disponibilizar promoções para os clientes dessa plataforma.&lt;/p&gt;

&lt;p&gt;Outro serviço dessa plataforma, será um plano de assinatura, possibilitando os clientes a terem vantagens dentro da plataforma.&lt;/p&gt;

&lt;p&gt;E também é preciso que se tenha um dashboard de acompanhamento de vendas por restaurante.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As informações acima podem gerar algum sentimento de desconforto, assumindo que a quantidade de pontos abordados é grande. &lt;em&gt;Quero te dizer que você é uma pessoa com sorte, por ter esse privilégio de ter esses dados em mãos&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Muitas vezes, o que será solicitado à você será para 💥 &lt;strong&gt;refazer um sistema já existente ou criar um outro usando outras tecnologias, com base (literalmente falando) no sistema anterior&lt;/strong&gt;, sem muita explicação e detalhes que poderiam te ajudar a levantar questões.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9c2q8nw73cokw860djdp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9c2q8nw73cokw860djdp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Então porque é que eu fico feliz com o compartilhamento dessa quantidade de informações? (&lt;em&gt;Alguns poderão dizer o contrário, e achar que não tem muita informação, 🤷🏻&lt;/em&gt;). Bem, o momento de você começar a extrair detalhes, está por vir 🙂.&lt;/p&gt;

&lt;p&gt;Vamos começar a destilar toda a informação que nos foi passada, começando por essa parte da conversa:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Estamos com a necessidade de criar uma plataforma como serviço que seja usada para realizar pedidos de refeições online. Essa plataforma vai cobrir desde o cadastro de um restaurante como parceiro até a entrega dos pedidos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inicialmente, você já toma conhecimento de uma informação muito importante: &lt;strong&gt;Criar uma plataforma SaaS para um FoodDelivery&lt;/strong&gt;. Essa informação é bastante técnica para um inicio de conversa, mas esse contexto de aplicação detectado, favorece entender qual será o modelo de negócio, além de levantar outras perguntas: &lt;em&gt;De que forma está se intencionando monetizar essa plataforma?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos para a outra parte da conversa, e analisar mais informações:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Queremos disponibilizar promoções para os clientes dessa plataforma. Além de ter planos de assinatura, possibilitando os clientes a terem vantagens dentro da plataforma.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fantástico! Algumas afirmações compartilhadas nessa parte da conversa, ajuda a identificar 2 macro-funcionalidades:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Promoções serão criadas e disponibilizadas para os clientes da plataforma e potenciais novos clientes.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Um programa de assinatura será criado e disponibilizado aos clientes, possibilitando aproveitar de benefícios para assinantes.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esses dois temas identificados acima, vão te favorecer sobre a forma de direcionar o foco para a perspectiva do &lt;strong&gt;QUÊ&lt;/strong&gt; será abordado em uma sessão aplicando Event Storming, por exemplo. Mas o nosso trabalho não para por aqui, e só está começando.&lt;/p&gt;

&lt;p&gt;Ainda podemos levantar questões que precisam ser anotadas, afim de serem compartilhadas na sessão de workshop. Existem diferentes perguntas que uma pessoa poderia levantar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como as promoções serão integradas nessa plataforma?&lt;/li&gt;
&lt;li&gt;Qual será o meio de veiculação dessas promoções? Email? Notificação no portal (aplicação)?&lt;/li&gt;
&lt;li&gt;Quando uma assinatura estiver perto de vencer, o que deve ser feito? Enviar uma promoção?&lt;/li&gt;
&lt;li&gt;Quando surgir um benefício associado a um plano, como notificar os clientes desse plano?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essas foram algumas perguntas que podem ser anotadas e levadas para serem discutidas junto aos especialistas de negócio e pessoas envolvidas dentro dessa sessão de Workshop, afim de também contribuir com a construção desse produto. &lt;em&gt;Não se esqueça de não só pensar nessas perguntas, mas também de tomar nota de todas elas.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Vamos analisar outra parte do contexto que nos foi compartilhado:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Quando um plano é contratado, o cliente receberá automaticamente o acesso ao sistema e a todos os benefícios desse plano, além de ser notificado sobre o contrato desse plano.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Até aqui, torna-se possível perceber algumas etapas de processos importantes que nos foram compartilhadas, e dentro desses processos estão contidas ações e eventos que vão dar suporte ao fluxo de negócio desenhado para atender às necessidades da empresa, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preparar as promoções de desconto&lt;/li&gt;
&lt;li&gt;Disponibilizar as promoções de desconto&lt;/li&gt;
&lt;li&gt;Preparação do contrato de assinatura do plano&lt;/li&gt;
&lt;li&gt;Pagamento do valor da assinatura&lt;/li&gt;
&lt;li&gt;Liberação de acesso&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ótimo! Agora já conseguimos extrair alguns processos e ações que vão ajudar durante a modelagem dos sub-domínios desse sistema. Mas ainda cabem algumas perguntas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ao disponibilizar uma promoção, como será enviada ao cliente? Na App? Email?&lt;/li&gt;
&lt;li&gt;Se o cliente quiser usar essa promoção no restaurante físico, será possível? Como?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se você chegou até essa parte do post, Parabéns! Você conheceu um processo de identificação de macro-funcionalidades, requisitos e aprendeu a explorar algumas questões importantes para enriquecer um workshop de descobertas e detalhamento de processos de negócio.&lt;/p&gt;

&lt;p&gt;Agora um conselho que pode ficar aqui é: Utilize essas técnicas usadas durante esse processo de identificação, mas reuna todas as informações levantadas até aqui, de maneira estruturada, afim de te ajudar durante as sessões.&lt;/p&gt;




&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Durante a jornada desse post, cheio de conceitos e abordagens que auxiliam na descoberta de informações necessárias para o desenvolvimento de qualquer sistema ou até mesmo de uma funcionalidade, buscou mostrar a importância de se ter como ferramenta um processo de trabalho objetivo, facilitando a comunicação das pessoas especialistas no negócio, construindo um produto digital consistente.&lt;/p&gt;

&lt;p&gt;Reunir as pessoas adequadas dentro de sessões de descobertas, ajuda no entendimento dos fluxos de negócio que estão sendo pensados e desejados, e que serão catalizadores para se ter uma movimentação para o digital, de forma coerente com que está sendo necessário para uma organização.&lt;/p&gt;

&lt;p&gt;📌 No próximo post vamos começar a usar esses conhecimentos e partir para um quadro 📋 de &lt;strong&gt;descoberta de sub-domínios&lt;/strong&gt; 😃.&lt;/p&gt;

&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.eventstorming.com/" rel="noopener noreferrer"&gt;https://www.eventstorming.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pt.wikipedia.org/wiki/Arqu%C3%A9tipo" rel="noopener noreferrer"&gt;https://pt.wikipedia.org/wiki/Arquétipo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ddd</category>
      <category>domaindrivendesign</category>
      <category>business</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Domain-Driven Design Estratégico: O Início</title>
      <dc:creator>José Roberto Araújo</dc:creator>
      <pubDate>Fri, 09 Feb 2024 10:04:58 +0000</pubDate>
      <link>https://dev.to/emergingcode/domain-driven-design-de-forma-estrategica-o-inicio-1df2</link>
      <guid>https://dev.to/emergingcode/domain-driven-design-de-forma-estrategica-o-inicio-1df2</guid>
      <description>&lt;p&gt;O Domain-Driven Design (DDD) é uma abordagem de modelagem de domínios de negócio que atrai minha atenção desde 2015. Desde então, tenho me aprofundado cada vez mais nos estudos e na prática dessa metodologia, aprimorando minhas habilidades em grandes empresas. Ao longo da minha carreira em grandes empresas, tive a oportunidade de aplicar os princípios do DDD em diversos projetos, aprofundando meu conhecimento e aprimorando minhas habilidades.&lt;/p&gt;

&lt;p&gt;A experiência em diferentes empresas com diferentes expectativas de negócio, molda a maneira como se olha para um projeto de tecnologia, onde antes o ponto principal e mais interessante, era conhecer a stack de tecnologia que estava sendo usada e quais eram os projetos de código existentes na empresa. Confesso que essa é a parte que também aquece o meu coração, como developer.&lt;/p&gt;

&lt;p&gt;Com o tempo, percebi que a tecnologia, embora fascinante para uma pessoa técnica, é apenas uma ferramenta que viabiliza o sucesso do negócio. No fim das contas, o que realmente importa é o domínio do negócio da empresa. Ou seja, não importan o quão inovadora é a tecnologia, linguagem de programação, cloud provider escolhido, se essas peças técnicas não estão sendo utilizadas para atingir o objetivo do negócio. Por outro lado, se a estrutura da organização da empresa também não estiver sob uma estrutura minimamente organizada, com áreas de atuação bem definidas e sua comunicação não estiver fluindo de forma clara, objetiva e, contextualizada, a tecnologia não vai ajudar nesse sentido.&lt;/p&gt;

&lt;p&gt;É aqui onde Domain-Driven Design entra em cena junto com a Lei de Conway.&lt;/p&gt;




&lt;h1&gt;
  
  
  Primeiro! Entenda o seu domínio 🔍
&lt;/h1&gt;

&lt;p&gt;Durante a minha caminhada profissional, percebo que a aplicação do Domain-Driven Design em projetos, tem se dado muito mais sob a forma tática do que utilizar ferramentas que deem suporte às técnicas de modelagem estratégica. Se você se desafiar a ir ao Github e procurar por DDD ou Domain-Driven Design, vão ser listados vários projetos que usam, basicamente, artefatos táticos: &lt;em&gt;Entidades, Agregados, Objetos de Valor&lt;/em&gt;, e que em sua maioria não contextualiza qual o dominio do problema está sendo trabalhado e quais foram as técnicas aplicadas para se chegar àquela estrutura de código. E isso é o que contribui para a geração dos famosos: &lt;strong&gt;Projetos DDD&lt;/strong&gt;. Usar as técnicas táticas não está errado, mas nomear um projeto como usando DDD, apenas por isso, é o que NUNCA deveria ter acontecido na história.&lt;/p&gt;

&lt;p&gt;Domain-Driven Design é uma abordagem de modelagem de negócio, o qual tem como fundamento compreender a contextualização de cada área de negócio, suas responsabilidades e objetivos. Cada uma dessas áreas podem ser nomeada de forma diferente, dependendo do tamanho da empresa, algumas chamam de &lt;em&gt;unidades de negócio&lt;/em&gt;, e empresas de larga escala, essas mesmas unidades de negócio, são denominadas: &lt;em&gt;Departamentos&lt;/em&gt;. A questão essencial por trás desses dois tipos de classificação, é a compreensão sobre o funcionamento do negócio em cada parte da empresa.&lt;/p&gt;

&lt;p&gt;Cada empresa trabalha sobre um nicho de negócio específico o que determina qual é o &lt;strong&gt;&lt;em&gt;Domínio&lt;/em&gt;&lt;/strong&gt; de atuação daquela empresa. (&lt;em&gt;claro que existem os concorrentes, mas isso não é questão para esse post&lt;/em&gt;) Por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;E-Commerce&lt;/em&gt;: este domínio pode incluir compras online, catálogo de produtos, processamento de pedidos, pagamentos e muitas outras partes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Tributação&lt;/em&gt;: neste domínio podemos encontrar áreas como imposto sobre o rendimento, imposto sobre as sociedades, cumprimento fiscal ou política fiscal&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Assistência Médica&lt;/em&gt;: Aqui pode incluir áreas como gerenciamento de pacientes, agendamento de consultas, registros médicos, gerenciamento de prescrições, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Logística&lt;/em&gt;: Nesse tipo de domínio pode existir armazenamento, transporte, gerenciamento de estoque, otimização de rotas ou programação de entrega&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como você pode perceber, a modelagem do negócio está essencialmente ligada ao setor que você está atuando neste momento. Freqüentemente, as empresas que operam no mesmo setor são semelhantes - ou seja, são representadas por modelos ou tipos de negócios básicos e padrão que representam aspectos essenciais de qualquer negócio ou indústria. Tais representações são chamadas de &lt;strong&gt;Arquétipos&lt;/strong&gt; – vou detalhar mais sobre que são Arquétipos, no post abordando os subdomínios. Isso não significa, entretanto, que todas essas partes (Subdomínios) funcionem da mesma maneira.&lt;/p&gt;

&lt;p&gt;E isso é algo que precisamos abordar em nossa análise de um domínio de negócios, sempre que construímos (ou reconstruímos) o sistema.&lt;/p&gt;

&lt;h1&gt;
  
  
  Lei de Conway ⚖️
&lt;/h1&gt;

&lt;p&gt;Toda empresa funciona com base na comunicação entre as pessoas e seus departamentos, o que se torna um fator essencial para uma boa condução de projetos ou uma grande confusão na execução e orquestração de projetos e roadmaps.&lt;/p&gt;

&lt;p&gt;É fato que, em arquitetura de sistemas, existe uma máxima chamada: &lt;strong&gt;Depende&lt;/strong&gt;! E essa simples palavra, demanda um ponto de reflexão grande sobre a necessidade de se aplicar alguma regra geral para todas as soluções. No entanto, existe uma um direcionamento que é regido por uma lei, o qual é fácil concordar devido a sua grande importância que é a poderosa: Lei de Conway (no inglês, Conway's Law).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Melvin Conway em 1967,&lt;/em&gt; criou essa idéia, que depois vem a se tornar uma Lei, a qual descreve:&lt;/p&gt;

&lt;p&gt;”&lt;em&gt;Organizações que desenham sistemas (de qualquer natureza) são obrigadas a produzir designs que são cópias das estruturas de comunicação dessas organizações&lt;/em&gt;”&lt;/p&gt;

&lt;p&gt;O que a Lei de Conway quer dizer é que é obrigatório que exista uma comunicação limpa, clara e transparente, e que aconteça de forma colaborativa entre as pessoas e departamentos, de forma a assegurar a compatibilidade entre os componentes (seja técnico ou de negócio). A estrutura técnica de um sistema vai refletir as fronteiras sociais das organizações que produzem essa comunicação.&lt;/p&gt;

&lt;p&gt;O interessante é que essa Lei foi aplicada, primariamente, no campo da arquitetura de software, entretando Conway direcionou a aplicação da Lei amplamente dentro de uma organização.&lt;/p&gt;

&lt;p&gt;Vamos imaginar uma situação hipotética onde você está trabalhando em um time responsável por um subdomínio de &lt;strong&gt;Entrega&lt;/strong&gt; (p*s.: abstraia aqui o tipo do Domínio principal*), dentro desse subdomínio, você vai se especializar em um nicho de conhecimento de negócio muito focado em leis logísticas, regras aplicadas à entregas, tracking das entregas, integração desse subdomínio com parceiros de tracking, dentre outros tantos conhecimentos. Só que agora, o seu time recebeu uma demanda que toca na parte te pagamentos e pedidos. Com essa demanda, chega também a obrigação de ter que atuar em outros subdomínios que você não tem o mínimo conhecimento, mas que a empresa acredita que esse tipo de operação e execução de roadmap, vai ajudar as pessoas a terem um conhecimento holístico do sistema. Legal, na teoria, não é mesmo? Mas claro que isso não funciona!&lt;/p&gt;

&lt;p&gt;É aqui que a Lei de Conway entra em cena, ajudando as empresas refinarem as comunicações, separação de responsabilidades de áreas e definir bem as fronteiras entre esses departamentos, afim de facilitar não só o desenho de uma arquitetura consistente, mas também ajudar na organização da topologia dos times. Imagine você uma pessoa da área de Marketing, agora ter que atuar no Financeiro da empresa? 🤔&lt;/p&gt;

&lt;h1&gt;
  
  
  Utilize ferramentas de modelagem 📝
&lt;/h1&gt;

&lt;p&gt;Bem, se você chegou até aqui, já deu para perceber que Domain-Driven Design vai muito além de Entidades e Agregadores, e até chegar ao momento da implementação, é necessário levantar informações e construir conhecimento sobre o Domínio do negócio onde você está trabalhando!&lt;/p&gt;

&lt;p&gt;Uma maneira de facilitar esse processo de descoberta e levantamento de informações sobre o negócio de uma empresa, é a utilização de ferramentas e o agendamento de workshops os quais vão ajudar a unir as pessoas certas e transformar esse momento, em um momento de descoberta transparente e colaborativa.&lt;/p&gt;

&lt;p&gt;Na maioria dos casos, eu tenho a prática de descobrir e descrever o caso de negócios (processos) mais crítico. Aquele para o qual o sistema será construído - total ou parcialmente, às vezes partes dos processos de negócios acontecem fora do sistema - um exemplo pode ser um processo em que uma etapa da solicitação é enviada ao sistema jurídico nacional. Devemos esperar algumas semanas pela resposta antes de continuar o processo em nossa empresa.&lt;/p&gt;

&lt;p&gt;Propor Workshops com as pessoas adequadas para estarem dentro dessa sessão, vai colaborar com o compartilhamento de conhecimento, isso porque provavelmente vão estar nessa sessão: Especialistas de negócio, pessoas de legal, desenvolvedores de sistemas legados (Ps.: &lt;em&gt;tendo em vista que essas pessoas podem ser as poucas que restam na empresa e que detem o conhecimento desses tipos de sistemas&lt;/em&gt;), Arquitetos/Staff/Principals. Essa sessão precisa transmitir o sentimento de que as pessoas passaram a entender o que acontece de uma maneira geral no sistema (&lt;em&gt;mas não serão especialistas em tudo&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Existem alguns métodos que você pode pensar em usar. Existem muitas maneiras diferentes de fazer isso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event Storming&lt;/li&gt;
&lt;li&gt;Domain Storytelling&lt;/li&gt;
&lt;li&gt;User Story Mapping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Qual seria o melhor método a ser utilizado? Para isso depende do contexto do projeto e pessoas envolvidas nessa sessão.&lt;/p&gt;

&lt;p&gt;Se o processo for novo, ou se eu obtiver a resposta de que a maioria dos participantes preferiria um workshop de post-its, o método que eu escolheria seria o &lt;strong&gt;Brainstorming usando Event Storming&lt;/strong&gt;, onde todos estão envolvidos.&lt;/p&gt;

&lt;p&gt;Caso o processo já existe ou se os participantes preferirem diagramas, eu preferiria um &lt;strong&gt;workshop utilizando Domain Storytelling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Em muitos casos, é simplesmente uma questão de preferência.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Esse post introduziu você sobre o prisma da parte estratégica do Domain-Driven Design. Também ficou claro que até aqui não foi abordado nenhum aspecto tático, diagramas ou designs sobre subdomínios, os tipos de entidades e agregadores dentro desses universos, nem muito menos delimitamos fronteiras através de Bounded Context (contextos delimitados) ou qualquer outro tópico relacionado a arquitetura de software ou padrões arquiteturais.&lt;/p&gt;

&lt;p&gt;Surpreso/a sobre esse tipo de abordagem? Se a resposta foi Sim! ÓTIMO! O Objetivo desse artigo foi atingido. Para darmos o próximo passo, precisamos seguir através do caminho da análise do negócio sobre a perspectiva de um determinado domínio e seus respectivos subdomínios, utilizando técnicas e ferramentas que nos dê capacidade de levantar as informações necessárias para construirmos a modelagem do negócio e da arquitetura do sistema, e isso vai dar todas as condições para desenvolver um sistema mais ajustado a realidade do negócio.&lt;/p&gt;

&lt;p&gt;No próximo post, vamos mergulhar no universo da modelagem do negócio para um &lt;strong&gt;Food Delivery&lt;/strong&gt;, onde vamos utilizar &lt;em&gt;Event Storming,&lt;/em&gt; onde vamos destilar alguns &lt;strong&gt;subdomínios&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Conway%27s_law"&gt;https://en.wikipedia.org/wiki/Conway%27s_law&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.eventstorming.com/"&gt;https://www.eventstorming.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://domainstorytelling.org/quick-start-guide"&gt;https://domainstorytelling.org/quick-start-guide&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ddd</category>
      <category>domaindrivendesign</category>
      <category>business</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>System design: PACELC: Uma extensão ao Teorema CAP</title>
      <dc:creator>José Roberto Araújo</dc:creator>
      <pubDate>Wed, 07 Jun 2023 12:14:14 +0000</pubDate>
      <link>https://dev.to/emergingcode/pacelc-a-extensao-do-teorema-cap-5dgc</link>
      <guid>https://dev.to/emergingcode/pacelc-a-extensao-do-teorema-cap-5dgc</guid>
      <description>&lt;p&gt;O que se entende sobre o Teorema CAP? E como o Teorema PACELC extende o CAP?&lt;/p&gt;

&lt;p&gt;No dia a dia do desenvolvimento de sistemas distribuídos, deveríamos ter a certeza de que muitas falhas, de diferentes tipos, vão acontecer. E esse é um Fato. Ignorar esses eventos abre margem para que as falácias de sistemas distribuídos entre na pauta de discussões sobre os problemas, os quais irão causar prejuízos para a arquitetura do sistema. E isso não é o que se espera de uma arquitetura robusta e tolerante a falhas, caso se tenha em consideração estratégias de design já válidas pela indústria de software.&lt;/p&gt;

&lt;p&gt;Abaixo listo as 8 falácias sobre Sistemas Distribuídos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A rede é confiável&lt;/li&gt;
&lt;li&gt;A latência da minha rede é zero&lt;/li&gt;
&lt;li&gt;A largura de banda da internet é grande o suficiente&lt;/li&gt;
&lt;li&gt;Minha rede está segura&lt;/li&gt;
&lt;li&gt;A topologia de redes não vai mudar&lt;/li&gt;
&lt;li&gt;Já temos um administrador de redes&lt;/li&gt;
&lt;li&gt;Não temos custo de transporte&lt;/li&gt;
&lt;li&gt;Minha rede é homogênea&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Durante a construção de arquiteturas desse porte, aparecerão tread-offs de todos os tipos e naturezas, e estar preparado para tomar as decisões que melhor se encaixam no seu contexto, vai fazer toda a diferença nos resultados do seu projeto.&lt;/p&gt;

&lt;p&gt;Diante de tantos desafios encontrados durante o planejamento, desenho e execução de sistemas distribuídos, existe algum guia, princípios ou alguma forma de balancear a escolha das tecnologias e, além disso, saber onde devo melhorar a arquitetura de um sistema? Considerando as várias características exigidas nesse tipo de solução?&lt;/p&gt;

&lt;p&gt;O Teorema CAP conta e resolve apenas uma parte da história. Apesar de atualmente ainda ser um teorema válido, existem muitas críticas a sua volta, devido algumas limitações terem sido detectadas no teorema. Então o que explica o teorema CAP? O que o faz ser uma verdade? Existe alguma alternativa?&lt;/p&gt;

&lt;h2&gt;
  
  
  Teorema CAP
&lt;/h2&gt;

&lt;p&gt;Criado por &lt;a href="https://en.wikipedia.org/wiki/Eric_Brewer_(scientist)"&gt;Eric Brewer&lt;/a&gt;, o &lt;a href="https://en.wikipedia.org/wiki/CAP_theorem"&gt;Teorema CAP&lt;/a&gt;, também conhecido como Brewer's theorem (Teorema de Brewer), apareceu pela primeira vez em 1998 e só foi publicado como teorema em 1999. A primeira versão do Teorema CAP, apareceu com base nos conceitos ACID, Base.&lt;/p&gt;

&lt;p&gt;O teorema CAP afirma que um sistema distribuído não pode ter mais do que 2 propriedades, dentre as 3 possíveis: &lt;strong&gt;Consistency, Availability e Partition tolerance&lt;/strong&gt; (&lt;em&gt;Consistência, Disponibilidade e Tolerância a partição)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As combinações dessas escolhas se resumem em: CA, CP e AP. Dentre as combinações, CA é uma das opções que gera alguma confusão em visualizar um caso de uso, tendo em vista que se um sistema não é partition-tolerant, essa característica vai obrigar esse sistema a abrir mão da CONSISTENCY ou da AVAILABILITY em caso de falha na rede.&lt;/p&gt;

&lt;p&gt;Portanto, o teorema CAP afirma, resumidamente, que: Na presença de falhas de rede, ou seja, partition failure, um sistema distribuído DEVE escolher entre Consistency ou Availability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ykc4n3b9g3fxf4ivkuk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ykc4n3b9g3fxf4ivkuk.png" alt="Teorema CAP" width="527" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Consistency
&lt;/h3&gt;

&lt;p&gt;Essa propriedade, afirma que todos os nodes possuem os mesmos dados ao mesmo tempo. Isso significa as aplicações pode ler e/ou escrever de/para qualquer um dos nós dentro dessa infraestrutura e, consequentemente, acessarão os mesmos dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhro5k38b0bidu1kwys8f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhro5k38b0bidu1kwys8f.png" alt="Consistência" width="545" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Availability
&lt;/h3&gt;

&lt;p&gt;Essa propriedade do teorema, afirma que toda operação que for recebida por um dos nós operantes e saudáveis deve retornar uma resposta. Mesmo com um problema severo na rede ou em algum dos nós, a operação recebida pela requisição DEVE terminar e dar uma resposta.&lt;/p&gt;

&lt;p&gt;Em resumo, essa propriedade refere-se a capacidade de um sistema permanecer acessível e operável, mesmo que 1 ou mais nós fiquem offline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvvtblwqh95bexes2d5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvvtblwqh95bexes2d5g.png" alt="Disponibilidade" width="415" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Partition tolerance
&lt;/h3&gt;

&lt;p&gt;Essa propriedade do teorema trabalha sobre a perspectiva de falhas de comunicação (ou intermitências/falhas de rede) entre dois nós do sistema. Essa característica fica evidente quando os dois nós estão UP, MAS esses nós não conseguem se comunicar.&lt;/p&gt;

&lt;p&gt;Sistemas tolerante a partição (Partition-tolerant) tem a capacidade de sustentar o funcionamento, mesmo em caso de falha de rede, ou seja, falha de comunicação entre os nós.&lt;/p&gt;

&lt;p&gt;Os dados são suficientemente replicados em combinações de nós e redes para manter o sistema funcionando durante interrupções intermitentes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc70si2nqb1b7bfdrn3s2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc70si2nqb1b7bfdrn3s2.png" alt="Tolerância a falha" width="427" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explicando o Teorema CAP
&lt;/h2&gt;

&lt;p&gt;A palavra TEOREMA assusta quem está conhecendo, pela primeira vez, esse termo, conceitos e abordagens. Até aqui já entendemos que a afirmação do teorema CAP diz que só se pode escolher 2 propriedades/características de sistema, dentre as 3 opções existentes. Por outro lado, existe uma forma que simplifica e ajuda a entender o raciocínio por trás desse teorema.&lt;/p&gt;

&lt;p&gt;Facilita pensar no teorema CAP, quando consideramos o (P), representado por Partition tolerance, entre dois nós diferentes. É importante perceber a relevância dessa característica porque, se por meio de uma falha de comunicação, apenas um desses nós tiver seu estado atualizado, o restante ficará inconsistente, o que nos leva a ter uma perda de (C), ou seja, Consistency, no entanto, se tivermos apenas 1 nós consistente, por meio da existência de (P), perdemos (A) Availability.&lt;/p&gt;

&lt;p&gt;O Teorema nos diz que não é possível ter um armazenamento de dados que esteja continuamente Disponível (A), Consistente (C) e Tolerante a qualquer falha (P). Porque, para ser consistente, todos os nós precisam ter o mesmo estado de atualização, na mesma ordem de ocorrência. Mas se ocorrer uma falha na comunicação, ou seja, a ocorrência de (P), as atualizações em um dos nós pode não chegar aos outros nós restantes, fazendo com que a aplicação possa ler dados desatualizados, devido ter caído em um dos nós que não foi atualizado anteriormente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implicações do Teorema
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AP&lt;/strong&gt;: Sistemas deste tipo respondem a consultas, mas os dados devolvidos podem nem sempre estar atualizados, com atualizações mais lentas dos dados mas “sempre” disponíveis.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CP&lt;/strong&gt;: Sistemas nessa categoria sempre retornam dados atualizados, mas alguns, ou mesmo todos os nós do sistema podem não responder se forem particionados. Ele fornece atualizações atômicas, mas pode levar a tempos limite.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CA&lt;/strong&gt;: Sistemas que se encaixam nessa categoria, sempre retornam dados atualizados quando não há partições. Por causa da última limitação, geralmente, tais sistemas são usados apenas dentro de uma máquina.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Críticas ao Teorema
&lt;/h2&gt;

&lt;p&gt;Em sistemas distribuídos, devemos assumir que vamos sim ter falhas de diferentes naturezas e não podemos evita-las, portanto, de acordo com o Teorema CAP um sistema distribuído só deveria escolher entre 2 propriedades: &lt;em&gt;Consistency ou Availability&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Banco de dados que prezam por &lt;strong&gt;ACID **(&lt;em&gt;Atomicity, Consistency, Isolation, Durability&lt;/em&gt;), focam em garantir a consistência dos dados, enquanto que **BASE&lt;/strong&gt; (&lt;em&gt;Basically available, Soft-state, Eventually consistent&lt;/em&gt;) prezam por retornar os dados presente em um dos nós, sem oferecer a garantia de que esse mesmo dado está presente em todos os outros nós.&lt;/p&gt;

&lt;p&gt;O Teorema CAP é criticado por sua simplificação dos acontecimentos e eventos que podem acontecer em uma arquitetura de sistemas distribuídos. Uma das pessoas que compartilhou algumas críticas foi &lt;a href="https://martin.kleppmann.com/"&gt;Martin Kleppmann&lt;/a&gt;, autor do livro: &lt;strong&gt;Designing Data-Intensive Applications&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A escolha entre consistência e disponibilidade realmente só é feita quando ocorre particionamento ou falha entre os nós. Em outros momentos, nenhuma compensação é necessária. Além disso, essas escolhas podem acontecer várias vezes dentro do mesmo sistema, e essas mesmas escolhas podem mudar dependendo da natureza da operação.&lt;/p&gt;

&lt;p&gt;Em sua definição original, &lt;strong&gt;o teorema CAP ignora atrasos de tempo&lt;/strong&gt;, embora na prática latência e particionamento são conceitos que estão intimamente ligados. Na prática, a natureza do Teorema CAP ocorre durante um timeout, período em que o sistema deve tomar uma decisão fundamental.&lt;/p&gt;

&lt;p&gt;Por fim, todas as três propriedades são mais contínuas do que binárias. Obviamente, a disponibilidade é contínua de 0 a 100 por cento, mas também há muitos níveis de consistência e até mesmo as partições são diferenciadas, incluindo divergências dentro do sistema sobre a existência ou não de uma partição.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teorema PACELC
&lt;/h2&gt;

&lt;p&gt;O Teorema PACELC, criado por Daniel J. Abadi, é a extensão ao teorema CAP, considerado como abordagem alternativa focada em design de sistemas distribuídos. A fundamentação desse teorema, tem como base o modelo desenhado e definido no teorema CAP, ou seja, todas as propriedades existentes no CAP como: Consistency, Availability e Partition tolerance foram reaproveitadas e, no PACELC foi adicionada a propriedade de Latency (Latência), continuando com uma combinação lógica de exclusão entre esses conceitos.&lt;/p&gt;

&lt;p&gt;O idealizador do PACELC, &lt;a href="https://en.wikipedia.org/wiki/Daniel_Abadi"&gt;Daniel Abadi&lt;/a&gt;, separa as operações em sistemas distribuídos em 2 modos:&lt;/p&gt;

&lt;p&gt;Operações **COM **falhas de comunicação (&lt;em&gt;Presença da Partition&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Operações **SEM **falhas de comunicação (&lt;em&gt;Ausência da Partition&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;A primeira parte do teorema (&lt;strong&gt;PAC&lt;/strong&gt;) é igual ao teorema CAP, e o &lt;strong&gt;ELC&lt;/strong&gt; é a extensão. Toda a tese assume que mantemos alta disponibilidade por replicação. Assim, quando há falha, prevalece o teorema CAP. Mas se não, ainda temos que considerar a compensação entre consistência e latência de um sistema replicado.&lt;/p&gt;

&lt;p&gt;Isso nos leva a raciocinar que as condições para o desenho de um sistema distribuído leva sempre em consideração uma propriedade, antes de todas as outras: Partição (&lt;em&gt;Partition&lt;/em&gt;), Ou seja, em havendo uma falha na comunicação (Partition) deve-se escolher uma propriedade entre Disponibilidade (&lt;em&gt;Availability&lt;/em&gt;) e Consistência (&lt;em&gt;Consistency&lt;/em&gt;), caso contrário, em situação normal de operação do sistema, deve-se escolher entre baixa Latência (&lt;em&gt;Latency&lt;/em&gt;) (&lt;em&gt;reduzir o tempo de resposta&lt;/em&gt;) e Consistência (&lt;em&gt;Consistency&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furpzsmnsz2qst1bmgfhy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furpzsmnsz2qst1bmgfhy.png" alt="Teorema PACELC" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplos de base de dados
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cassandra e DynamoDB&lt;/strong&gt;: São PA/EL, ou seja, eles preferem garantir disponibilidade (availability) ao invés de consistência, quando uma falha de comunicação acontece (Partition), caso contrário, eles optam por baixa latência (Latency)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SQLServer, MySQL, BigTable e HBase&lt;/strong&gt;: Por exemplo, são sistemas PC/EC: Eles sempre escolherão a consistência, abrindo mão da disponibilidade e menor latência.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O teorema PACELC afirma que, em um sistema que replica dados: os teoremas CAP e PACELC ajudam os sistemas distribuídos a escolher um equilíbrio desejável entre várias características distribuídas, como consistência, disponibilidade, tolerância à partição e latência.&lt;/p&gt;

&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing"&gt;https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/PACELC_theorem"&gt;https://en.wikipedia.org/wiki/PACELC_theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/CAP_theorem"&gt;https://en.wikipedia.org/wiki/CAP_theorem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://martin.kleppmann.com/2015/05/11/please-stop-calling-databases-cp-or-ap.html"&gt;https://martin.kleppmann.com/2015/05/11/please-stop-calling-databases-cp-or-ap.html&lt;/a&gt;
&lt;a href="https://www.cl.cam.ac.uk/research/dtg/www/files/publications/public/mk428/cap-critique.pdf"&gt;https://www.cl.cam.ac.uk/research/dtg/www/files/publications/public/mk428/cap-critique.pdf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://designgurus.io/blog/system-design-interview-basics-cap-vs-pacelc"&gt;https://designgurus.io/blog/system-design-interview-basics-cap-vs-pacelc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cap</category>
      <category>pacelc</category>
      <category>distributedsystems</category>
      <category>captheorem</category>
    </item>
    <item>
      <title>Event-Driven: Diferenças entre mensagens, eventos e comandos</title>
      <dc:creator>José Roberto Araújo</dc:creator>
      <pubDate>Tue, 18 Oct 2022 22:16:10 +0000</pubDate>
      <link>https://dev.to/emergingcode/event-driven-diferencas-entre-mensagens-eventos-e-comandos-4eg9</link>
      <guid>https://dev.to/emergingcode/event-driven-diferencas-entre-mensagens-eventos-e-comandos-4eg9</guid>
      <description>&lt;p&gt;A arquitetura de sistemas distribuídos tem como fundamento a comunicação de sistemas no formato assíncrono, baseando-se na troca de mensagens entre sistemas ou mesmo entre seus módulos. &lt;/p&gt;

&lt;p&gt;Esse tipo de arquitetura compreende duas variações de mensagens: Eventos e Comandos. Esses dois tipos de mensagens possuem propósitos distintos, a nomeação desses tipos são determinados com base em suas intenções, o proprietário muda mediante o contexto, ou seja, é perceptível que tudo isso faz diferença durante a modelagem de uma mensagem em uma arquitetura Event-Driven e pode, consideravelmente, mudar a experiência do usuário final.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mensagens
&lt;/h2&gt;

&lt;p&gt;Toda comunicação baseia-se em uma mensagem. Quando você vai ao mercado perto da sua casa e tem dúvida sobre alguma coisa, o que acontece? Acontece, nesse momento, a abertura da comunicação entre duas partes: Você e uma outra pessoa (no mínimo 2 partes precisam existir para acontecer uma comunicação). Quando você quer enviar uma mensagem para alguém, através de algum aplicativo, o que você vai fazer é: &lt;em&gt;Enviar uma mensagem&lt;/em&gt;! -- Não existe outra forma de ter comunicação, síncrona ou assíncrona sem existir uma: &lt;strong&gt;Mensagem&lt;/strong&gt;. Sempre vamos ter um Produtor de mensagem e um consumidor dessa mesma mensagem&lt;/p&gt;

&lt;p&gt;Em uma arquitetura Event-Driven não é diferente, se uma aplicação/módulo que conversar com outro, precisa existir uma comunicação através de uma: &lt;strong&gt;Mensagem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;E ai você pode virar pra mim e dizer: Poxa, bem que essa parte do artigo podia ser ignorada, né? Pois é! poderia ser ignorado SE os fundamentos não fossem tão importantes para o entendimento do todo.&lt;/p&gt;

&lt;p&gt;Entender o básico, vai ajudar você no dia a dia a distinguir as diferenças entre os dois tipos de mensagens e entender quando e porquê usar cada um deles, além de entender o impacto que o uso equivocado desses tipos, pode causar na experiência com o usuário da sua aplicaçao, além de trazer impactos em COMO será pensada a arquitetura do sistema seja no Backend ou na experiência com o usuário.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgi6eg02trn051ztnzai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgi6eg02trn051ztnzai.png" alt="Mensagem sendo enviada e consumida"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Comandos
&lt;/h2&gt;

&lt;p&gt;Comandos tem um propósito bem definido: Executar um &lt;strong&gt;Comportamento&lt;/strong&gt;. Façamos aqui uma analogia: Quando você entra em um ambiente da sua casa e ele está com as lâmpadas apagadas, o que você faz? Aciona o interruptor e a lâmpada é acesa. O que acontece aqui é que foi enviado uma mensagem no formato de comando, o sistema elétrico reconheceu o comando e executou uma ação que foi acender a lâmpada e a resposta foi ter a lâmpada acesa.&lt;/p&gt;

&lt;p&gt;Em uma arquitetura de sistemas distribuídos, também existe o envio de mensagens com a intenção de executar operações dentro de outros sistemas. É interessante observar que existem sistemas ou partes de um sistema que expõem suas capacidades/funcionalidades através de comandos. &lt;/p&gt;

&lt;p&gt;Torna-se evidente que, ao executar um comando, o agente de execução espera por uma resposta ao comando enviado. Nesse caso, pode-se associar um comando a uma ação síncrona, onde o agente que enviou o comando fica aguardando o receptor do comando receber o tal comando, validar o payload, executar a operação e retornar dizendo o estado da operação.&lt;/p&gt;

&lt;p&gt;Há quem diga que comandos podem ser geridos de forma assíncrona, e digo: Podem! Mas isso muda muito as regras do jogo e também dependendo de onde o comando foi originado, a resposta síncrona precisa acontecer dentro alguns segundos depois que o agente produtor enviou o comando, afim de dar um feedback, mais rápido possível, para quem produziu o comando.&lt;/p&gt;

&lt;p&gt;Então pense bem: A origem do comando pode mudar completamente a experiência do usuário e, consequentemente, a abordagem arquitetural.&lt;/p&gt;

&lt;p&gt;Abaixo existem 2 fronteiras lógicas diferentes, Pedido e Pagamento, onde cada uma delas envia um comando, mas haverá apenas 1 lugar dentro da arquitetura que terá a responsabilidade de saber reconhecer, validar, executar e responder a um comando. É o consumidor ou o Handler desse comando. É onde a regra do negócio será executada.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ognajmauz8kndj72017.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ognajmauz8kndj72017.png" alt="Comando de criação de pedido"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyh49p688is5ib2gsefpl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyh49p688is5ib2gsefpl.png" alt="Comando de preparação de pedido"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Os dois exemplos acima estão usando uma Queue para gerir a produção e o consumo de mensagens desse tipo, afim de focarmos na abordagem da comunicação de sistemas distribuídos.&lt;/p&gt;

&lt;p&gt;Comandos podem ser enviados de várias boundaries (limites) diferentes, ou seja, pode existir vários produtores diferentes para um mesmo comando. É quesionável? Bem! Pense em módulo de email. Um email pode ser disparado tanto pelo módulo de pedido, quando pelo módulo de registro de usuário pedindo para confirmar o cadastro. Nesse caso, existem 2 boundaries distintas, que podem enviar comandos para envio de emails.&lt;/p&gt;

&lt;p&gt;A forma como se modela e nomeia um comando importa e faz toda a diferença. Perceba nos dois desenhos acima que, em nenhum momento, os comandos foram nomeados como: &lt;em&gt;CriarPedido&lt;/em&gt;, &lt;em&gt;AtualizarPedido&lt;/em&gt;, &lt;em&gt;DeletarPedido&lt;/em&gt;. Essas ações constituem significados específicos e estão ligadas, diretamente, as intenções do negócio. Por isso é importante dar nomes coerentes aos comandos, como: &lt;strong&gt;AdicionarPedido&lt;/strong&gt;, &lt;strong&gt;AjustarEstoque&lt;/strong&gt;, &lt;strong&gt;PrepararPedido&lt;/strong&gt;, &lt;strong&gt;EnviarPedido&lt;/strong&gt;, etc. O comando &lt;strong&gt;PrepararPedido&lt;/strong&gt;, sendo enviado a partir da boundary de Pagamento, quer dizer que o pagamento já foi realizado e que o pedido pode ser preparado para ser enviado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eventos
&lt;/h2&gt;

&lt;p&gt;Tudo o que você viu no passado, não pode desvisto. Nada do que aconteceu no passado pode ser desfeito, mas o que aconteceu pode ser notificado/publicado para que alguém que tenha interesse nessa informação possa consumir. Essa é a premissa dos eventos, notificar o mundo externo que algo aconteceu.&lt;/p&gt;

&lt;p&gt;Imagine o cenário onde você pede para alguém ir ao mercado comprar alguma comida que você deseja muito, é essa pessoa envia uma mensagem para você, dizendo: &lt;strong&gt;Comida comprada!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os eventos possuem 2 partes, assim como os comandos. A primeira parte é o produtor da mensagem, é quem DETEM o Ownership do contrato da mensagem do tipo Evento, e esse produtor vai notificar o mundo externo sobre algo que já aconteceu. A segunda parte é a parte que consome esses eventos, ou seja, um consumer ou um handler, e que pode realizar alguma operação com base nas informações do payload desse tal evento.&lt;/p&gt;

&lt;p&gt;O diagrama abaixo ilustra um único publicador (publisher/producer) de evento e vários consumidores interessados nesse evento:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj470gm8atslkdlrmusoc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj470gm8atslkdlrmusoc.png" alt="Evento de Pedido adicionado"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Através da ilustração do diagrama, é possível perceber que só existe uma única boundary responsável por produzir esse tal evento. É esse Contexto Delimitado (Bounded Context) que tem a lógica de o que produzir, qual payload quer compartilhar (dados) com o mundo externo e quando esse evento deve ser publicado.&lt;/p&gt;

&lt;p&gt;O Consumidor de um evento, pode viver dentro de muitos contextos delimitados (bounded context) diferentes, com interesse em consumir o mesmo evento e realizar operações de lógica de negócio dentro de suas fronteiras. Não é obrigado existir sempre um consumidor de eventos, pode existir ZERO ou MUITOS.&lt;/p&gt;

&lt;p&gt;Nomear os eventos é essencial para que a comunicação entre as boundaries (fronteiras) faça sentido e seja fácil identificar a intenção de cada evento. Uma vez que os eventos são algo que ocorreu no passado, fica claro que a nomenclatura deles DEVE ficar no passado. Como exemplos temos: PedidoAdicionado, EntregaRecebida, EmailEnviado, PagamentoProcessadoComSucesso. Esses nomes deixam claro qual é a intenção de comunicação dos eventos.&lt;/p&gt;

&lt;p&gt;Ao modelar sistemas usando a abordagem do Domain-Driven Design (DDD), é comum perceber que dentro de cada contexto delimitado (bounded context) ações/operações que serão executadas é o geram como resultado, o que chamamos de: Eventos de Domínio. Existem alguns tipos diferentes de eventos e que são usados com finalidades específicas, como por exemplo: Eventos de integração. Em outro artigo, falarei sobre os diferentes tipos de eventos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comandos vs Eventos
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Objetivo&lt;/th&gt;
&lt;th&gt;Comandos&lt;/th&gt;
&lt;th&gt;Eventos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Propósito&lt;/td&gt;
&lt;td&gt;Executar um comportamento&lt;/td&gt;
&lt;td&gt;Expor que algo aconteceu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proprietário&lt;/td&gt;
&lt;td&gt;Propriedade do consumidor&lt;/td&gt;
&lt;td&gt;Propriedade do produtor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consumidores&lt;/td&gt;
&lt;td&gt;Tem 1 consumidor&lt;/td&gt;
&lt;td&gt;Zero ou muitos consumidores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Produtores&lt;/td&gt;
&lt;td&gt;Muitos produtores&lt;/td&gt;
&lt;td&gt;Tem 1 produtor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nomenclatura&lt;/td&gt;
&lt;td&gt;Verbo (indicar ação)&lt;/td&gt;
&lt;td&gt;Passado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A premissa de uma arquitetura Event-Driven não é apenas lidar com eventos, mas sim modelar a comunicação entre sistemas, através de mensagens, e essas terão suas classificações dependendo da intenção do conteúdo de uma mensagem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://codeopinion.com/commands-events-whats-the-difference/" rel="noopener noreferrer"&gt;https://codeopinion.com/commands-events-whats-the-difference/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://event-driven.io/en/whats_the_difference_between_event_and_command/" rel="noopener noreferrer"&gt;https://event-driven.io/en/whats_the_difference_between_event_and_command/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.enterpriseintegrationpatterns.com/CommandMessage.html" rel="noopener noreferrer"&gt;https://www.enterpriseintegrationpatterns.com/CommandMessage.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.enterpriseintegrationpatterns.com/EventMessage.html" rel="noopener noreferrer"&gt;https://www.enterpriseintegrationpatterns.com/EventMessage.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Junte-se a nossa comunidade
&lt;/h2&gt;

&lt;p&gt;No &lt;a href="https://www.youtube.com/c/emergingcode" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt; você vai encontrar vídeos sobre System Design, Software Architecture. Quer conversar sobre Domain-Driven Design, System Design, Software Architecture? Então faça parte da nossa comunidade no &lt;a href="https://discord.gg/RbJyNbvgGt" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Se quiser se aprofundar mais sobre Event-Driven e CQRS, acesse nosso curso de &lt;a href="https://www.emergingcode.com.br/arquitetura-de-software-cqrs" rel="noopener noreferrer"&gt;Arquitetura CQRS&lt;/a&gt; e acesse o repositório do projeto no &lt;a href="https://github.com/emergingcode/as-cqrs-emergingbooking" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>eventdriven</category>
      <category>distributedsystems</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
