Como usar PlantUML para projetar diagramas como código e implantá-los a partir do seu Pipeline CI/CD
Introdução
Mudar diagramas de software é difícil. O simples ato de adicionar uma nova caixa pode exigir que arrastemos todas as caixas existentes e reorganizemos o diagrama. Esta é uma das principais razões pelas quais os diagramas de software são constantemente deixados depreciados após os primeiros estágios do processo de desenvolvimento.
Neste post, mostrarei como definir diagramas como código pode ajudar a projetar e atualizar diagramas de software e como automatizar o processo de atualização da documentação com esses diagramas.
Por que criar diagramas como código?
Fácil de mudar: Basta mudar o código e os elementos do diagrama são renderizados em uma boa posição (às vezes pode precisar de alguns ajustes);
Reutilização de código: Componentes, sprites e funções podem ser definidos e compartilhados para serem usados em outros diagramas. Podemos usar loops e condições para tornar esses trechos de código ainda mais reutilizáveis. Detalhes aqui;
Histórico de mudanças: Por ser código, suas versões podem ser rastreadas e comparadas com sistemas de controle de versão, como o Git, por exemplo;
Estilo único em todo o diagrama: A menos que explicitado, todos os elementos do diagrama terão o mesmo estilo, sem necessidade de copiar o estilo de um elemento para outro ou ter que redimensionar todas as caixas após alterar o tamanho de uma;
Inclusivo: Todos na equipe podem fazer checkout do código e alterá-lo sem medo porque as mudanças podem ser rastreadas e o estilo é o mesmo para todos.
PlantUML
PlantUML é uma ferramenta de código aberto altamente personalizável que nos permite criar diagramas usando código. Apesar do nome, ele suporta muitos tipos de diagramas além de diagramas UML. Ele tem sua própria linguagem e algumas extensões para outras linguagens como AsciiMath, Creole e LaTeX.
PlantUML é uma ferramenta de linha de comando Java. Podemos executá-lo a partir da linha de comando, mas a melhor experiência é com uma extensão do Visual Studio Code.
Renderizando a partir do Visual Studio Code
Existe uma extensão que integra o PlantUML com o Visual Studio Code.
Ele oferece realce de sintaxe e uma visualização do diagrama ao lado durante a edição e opções para exportar os diagramas do projeto atual ou de todos, além de outros recursos.
Realce de sintaxe e visualização do diagrama
Após instalar a extensão, abra a paleta de comandos e procure por PlantUML para ver as opções disponíveis.
ℹ️ Você pode querer incluir o caminho para o arquivo plantuml.jar na variável de ambiente PATH para poder usá-lo em qualquer diretório.
Em seguida, para gerar o diagrama para um arquivo de origem, basta executar o seguinte comando:
java -jar plantuml.jar Sequence.puml
Também podemos gerar os diagramas para mais de um arquivo usando padrões glob:
java -jar plantuml.jar *.puml
Diagramas C4
O modelo C4 é uma abordagem diferente para projetar diagramas de arquitetura de software. Eu falei sobre isso no meu post anterior.
PlantUML tem suporte nativo para Diagramas C4. Precisamos apenas incluir a biblioteca e usar seus elementos.
Aqui estão alguns exemplos:
Diagrama de Contexto do Sistema
Diagrama de Contexto do Sistema
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@startumlC4_SystemContext!include<C4/C4_Context>lefttorightdirectionPerson(user,"User","Funcionário da empresa que tem acesso ao sistema de RH")System(hrSystem,"Sistema de RH","Permite que os usuários gerenciem dados pessoais e contrato dos funcionários da empresa")System_Ext(emailSystem,"Sistema de E-mail","Responsável por enfileirar e enviar e-mails")Rel(user,hrSystem,"Criar e alterar informações pessoais e de contrato do funcionário","")Rel(hrSystem,emailSystem,"Envia e-mails de notificação usando","")@enduml
@startumlC4_HRSystem_Containers!defineDEVICONShttps://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons!defineAWSPumlhttps://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist!include<C4/C4_Container>!includeDEVICONS/msql_server.puml!includeDEVICONS/dotnet.puml!includeAWSPuml/AWSCommon.puml!includeAWSPuml/ApplicationIntegration/SimpleQueueServiceQueue.pumllefttorightdirectionPerson(user,"User","Funcionário da empresa que tem acesso ao sistema de RH")System_Boundary(hrSystem,"Sistema de RH"){Container(webApp,"Aplicativo Web","ASP.NET 7 Application","Fornece as funcionalidades do sistema através do navegador web",$sprite="dotnet")Container(backgroundService,"Serviço de E-mail",".NET 7 Application","Serviço em segundo plano que lê uma fila para alterações de dados do funcionário e envia e-mails de notificação para os funcionários",$sprite="dotnet")ContainerDb(database,"Banco de Dados","SQL Server 2022","Armazena dados de funcionários e contratos",$sprite="msql_server")ContainerQueue(emailQueue,"Fila","AWS SQS","Armazena alterações de dados do funcionário",$sprite="SimpleQueueServiceQueue")}System_Ext(emailSystem,"Sistema de E-mail","Responsável por enfileirar e enviar e-mails")Rel(user,webApp,"Criar e alterar informações pessoais e de contrato do funcionário","")Rel(webApp,database,"Lê / Escreve","")Rel(webApp,emailQueue,"Escreve notificações para","")Rel(backgroundService,emailQueue,"Lê notificações de","")Rel(backgroundService,database,"Lê dados de funcionários de","")Rel(backgroundService,emailSystem,"Envia e-mails usando","")@enduml
@startumlC4_HRSystem_WebApp_Components!defineDEVICONShttps://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons!defineAWSPumlhttps://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v14.0/dist!include<C4/C4_Component>!includeDEVICONS/msql_server.puml!includeAWSPuml/AWSCommon.puml!includeAWSPuml/ApplicationIntegration/SimpleQueueServiceQueue.pumllefttorightdirectionContainer(webApp,"Aplicativo Web","ASP.NET 7 Application","Fornece as funcionalidades do sistema através do navegador web",$sprite="dotnet")Container_Boundary(webApp,"Aplicativo Web"){Component(employeesController,"Controlador de Funcionários","Fornece acesso às funcionalidades relacionadas aos funcionários")Component(registerEmployeesUseCase,"Caso de Uso de Registro de Funcionário","Orquestra o caso de uso de registrar um novo funcionário")Component(employeeDataQueueService,"Serviço de Fila de Dados de Funcionários","Fornece funcionalidades para se comunicar com a fila")Component(employeeRepository,"Repositório de Funcionários","Fornece funcionalidades para se comunicar com a tabela de banco de dados de funcionários")Component(loginController,"Controlador de Login","Controlador ASP.NET Core","Permite que os usuários se autentiquem no aplicativo web")Rel(employeesController,registerEmployeesUseCase,"Usa")Rel(registerEmployeesUseCase,employeeDataQueueService,"Usa")Rel(registerEmployeesUseCase,employeeRepository,"Usa")}ContainerDb(database,"Banco de Dados","SQL Server 2022","Armazena dados de funcionários e contratos",$sprite="msql_server")ContainerQueue(emailQueue,"Fila","AWS SQS","Armazena alterações de dados do funcionário",$sprite="SimpleQueueServiceQueue")Rel(employeeRepository,database,"Escreve informações do funcionário","")Rel(employeeDataQueueService,emailQueue,"Escreve notificações para","")@enduml
Mais exemplos
Aqui estão mais exemplos do que pode ser feito com PlantUML.
Variáveis e cores
Neste exemplo, criei um diagrama de sequência e usei variáveis para reutilizar os verbos HTTP formatados nas mensagens:
Um diagrama legal que o PlantUML pode gerar é o diagrama JSON, mostrando as propriedades e os dados de um JSON. Para gerar um diagrama JSON, basta usar os símbolos @startjson e @endjson e colar o conteúdo JSON entre eles.
PlantUML é extensível, então podemos criar ou importar elementos personalizados para usar em nossos diagramas. Um exemplo são os Ícones AWS para PlantUML. Ele tem elementos para representar a maioria dos principais serviços da AWS.
Para usá-lo, precisamos importar os elementos personalizados com o comando !import.
Neste exemplo, usei o comando !define para definir uma variável AWSPuml com o URL base e usei em todas as importações. Isso ajuda quando precisamos atualizar a versão dos objetos e também torna o código mais limpo.
PlantUML suporta alguns temas por padrão. Basta usar o comando !theme seguido pelo nome do tema:
1
2
3
4
@startuml
!theme materia
...
@enduml
Aqui está o diagrama de sequência anterior com o tema Materia:
Aqui podemos ver uma galeria com os temas disponíveis.
Automatizando a publicação do diagrama
Criei um site de documentação como um exemplo de como gerar diagramas PlantUML no pipeline CI/CD. Quando os diagramas são commitados no repositório, o pipeline os renderiza como imagens e a documentação é atualizada automaticamente.
Site de documentação atualizado pelo pipeline CI/CD
Simon Brown, criador do modelo C4, tem um conceito muito interessante chamado Diagrama como código 2.0 no qual um código de modelo pode gerar vários diagramas. Mais detalhes em seu post no blog.
Ele construiu uma ferramenta chamada Structurizr para isso.