Diagram as Code

As far as I remember from early on in my career to this day there was always a necessity of putting on a page (or slide) some sort of diagram to explain a concept, document software architecture or make a case. It is the famous "A picture is worth a thousand words".

Picture in the market
tough market for words

It is very important to point out that creating clean, concise and well thought abstractions and putting those in a diagram is not a simple task. Being intentional and transmitting a clear message with a one-pager is even harder. If you want to dive deeper, Gregor Hohpe has a chapter on his book The Software Architect Elevator called "Diagram-Driven Design" or if you are a video person, he covers part of the subject on his AWS re:Invent 2022 talk - The architect elevator: Connecting the boardroom and IT.

The first and the most important thing that comes to my mind when talking about diagrams in the software industry is: we need to create (or adjust) diagrams according to the target audience. Seems obvious, but sometimes we need to state the obvious, so here we go: please don't present a UML (Unified Modeling Language) class diagram to a senior executive who just want to have a grasp on how your application works and integrates with the rest of the world. That means that using one-diagram-to-rule-them-all as a strategy won't work.

But, creating multiple diagrams for different audiences without some level of consistency and leaving them in tools such as PowerPoint presentations, Miro, Draw.io or Excalidraw won't help much either. This is less about tooling preferences and more about having a central location to store, version, search and document diagrams with some consistent notation.

AWS is a good example of what I'm talking about here with its Reference Architecture Diagrams Page in case you are curious. You could also implement something like this in many many different ways and the right answer for you (and your organization) will change based on how your teams are organized, who is responsible for maintaining the documentation/diagrams and the tools you are allowed (or, sometimes, obligated) to use. Diagram as code is one of the multiple ways that can help you solve this problem.

In short, "Diagram as code" allows you (and your organization) to manage your diagrams in the same way you handle your code. You write text following a syntax (like, coding), store this artifact in a version control system (like, GitHub) and when you build or render the text-based-code you wrote the diagram will be generated! This concept is far from new, PlantUML was released in 2009 but with more and more teams moving to use git as the single source of truth for their work (GitOps you say?) software engineering technical documentation (which hopefully also include diagrams) is in the mix to be part of this movement.

Things are never plain, simple and easy and of course there are several ways of implementing Diagram as Code. Here are a few that I tested:

PlantUML

I've already mentioned PlantUML and after testing I can say it is very flexible, you can go from basic UML diagrams to non-UML stuff like an Archimate diagram. In order to run this locally there are a few steps that you need to perform (all documented in their site) and below is a snippet of how you can have a diagram generated:

@startuml

User -> (Front-End App): open
(Front-End App) -> (Back-end App): call

@enduml

image:

Plant UML
PlantUML generated image
Mermaid

Mermaid is another option that works very similar to PlantUML but the most exciting difference (at least for me) is that if you are familiar with Markdown you should have no problem learning the syntax and using it since you just "code" a mermaid block in your .md file and done the diagram will be rendered for you. GitHub natively supports the rendering when you push a .md file there and also Visual Studio Code does the same when you use the preview. For use cases where you are documenting stuff using Markdown, evolving to use Mermaid for your diagrams and keeping both together in the same .md file is pretty simple and neat! Here is an example:

```mermaid

    flowchart LR
    user(User)-- open -->front(Front-End App)
    front-- calls -->back(Back-End App)

```

image:

Mermaid
Mermaid generated image
Diagrams (by Mingrammer)

Are you a Python developer and want to have a Diagram as Code option using Python? Your problem can be solved with Diagrams! When reading the documentation and the examples the site has, I felt that in this case it is more about cloud product icons and system/solution architecture diagrams and less about generic blocks/flowchart support by default. I say default because after some digging in their Github issues I discovered that you can use all Graphviz shapes in order to have generic shapes and forms like in the example below:

from diagrams import Diagram, Node, Edge
from diagrams.onprem.client import User

with Diagram(filename="user_front_and_back", outformat="png", show=False, direction="LR") as diag:

    user = User(label="User")
    front = Node(label="Front-End App", shape="rectangle", style="rounded", labelloc="c")
    back = Node(label="Back-End App", shape="rectangle", style="rounded", labelloc="c")

    user >> Edge(label="open") >> front
    front >> Edge(label="calls") >> back

diag

It feels wrong to write a Python code and post it online without having the import pandas as pd and import numpy as np at the top. Will this work without those 2 magic sentences? Not sure never seen a gist of Python code online without them 👀. Ok sorry it was a bad joke... let's get back... here goes the image that was generated when executing the code:

Diagrams
Diagrams generated image
Structurizr

Simon Brown created the C4 model "as a way to help software development teams describe and communicate software architecture, both during up-front design sessions and when retrospectively documenting an existing codebase" according to their website. As it is a model and it got traction with software developers and architects people started building things around the C4 concept. To prove my point, you can use all the three mentioned Diagram as Code options above to generate C4 diagrams: PlantUML C4 library, Mermaid C4 syntax and Diagrams C4 package.

But why I've started talking about C4 in the Structurizr part of the post? Well, because Structurizr was specially designed to support the C4 model in a Diagram as Code way. This is no coincidence since the author of the model is the same person who wrote Structurizr. Simon gave a nice presentation talking about his perspectives on Diagram as Code 2.0 if you are interested.

Another thing to point out is that Structurizr works in a different way. You write code using a modeling language and that can generate multiple views. When working with a model (Archimate is another example of a modeling language) you define the components and the relationships only once and you can reuse those across diagrams (it is a one to many relationship). No? Still confusing? Let's try an example: If I create a component called "Front-End App" and use this component in 10 diagrams if later on we change this component to "Web App" I need to change it only once and all my 10 views will be updated.

Code:

workspace {

model {
    user = person "User"
    softwareSystem = softwareSystem "Software System" {
        front = container "Front-End App" {
            user -> this "open"
        }
        container "Back-end App" {
            front -> this "calls"
        }
    }
}

views {
    systemContext softwareSystem {
        include *
        autolayout lr
    }

    container softwareSystem {
        include *
        autolayout lr
    }

    theme default
}

}

image:

Structurizr
Structurizr generated image
Backstage

Spotify understood the importance of centralizing a bunch of stuff in a single Internal Developer Portal and decided to invest/create Backstage. Their approach to software architecture documentation/visualization evolved around that. What they did exactly on the Diagram part? They created the Spotify System Model (which is derived from the C4 model) and they automated the rendering of architecture diagrams using the Backstage structure they had in place. Each team/squad add the necessary information for their respective services using the service catalog YAML file and Backstage does the rest. It is an interesting approach specially to highlight dependencies. If you are using Backstage (and a lot of companies are adopting Backstage nowadays) this is no-brainier to follow and have some of your diagrams automatically generated right next to the services documentation. Check-out this link for more details.

A final comment to conclude this post is: documenting the intentional abstractions/diagrams (as a code or not) is a completely different game from brainstorming exercises. Those are two different things with different outcomes and objectives in my view. When brainstorming something with the team or someone else remotely (without a real-word whiteboard and markers) I prefer Draw.io or Excalidraw because they are easy to use with drag-and-drop shapes/arrows and have specific features around collaboration that accelerate the discussion you are in.

In summary if you want diagrams that can be version-controlled, automated, and maintainable like software pick one option that works for you and your team and Happy Diagramming as Code everyone!

Leave a Comment

Your email address will not be published. Required fields are marked *