Modelling software architecture with PlantUML
Tags: architecture, c4model, plantuml, productivity
Published: 2020-07-03 10:35:40

---
title: Modelling software architecture with PlantUML
published: true
description: 
series: Software architecture diagrams as text
tags: #softwarearchitecture #c4model #plantuml #productivity
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/0j1lzi3balzorc4dtndm.png
---

Creating software architecture diagrams from text is becoming more popular. Text is easy to work with, and it's version controllable, so it can be stored alongside your source code. Tools like [PlantUML](https://plantuml.com), [Mermaid](https://mermaid-js.github.io/mermaid/#/), and [WebSequenceDiagrams](https://www.websequencediagrams.com) have auto-layout algorithms that allow us to focus on content too.

In conjunction with the [C4 model](https://c4model.com), it's relatively straightforward to create a collection of diagrams to describe the project/product you're working on, at different levels of abstraction. For example, here's a [System Context diagram](https://c4model.com/#SystemContextDiagram) to describe a pet clinic information management system.

![An example System Context diagram](https://dev-to-uploads.s3.amazonaws.com/i/5hkyyxy6iqy2t2rddrvs.png)

And here's a [Container diagram](https://c4model.com/#ContainerDiagram) showing the internals of the software system.

![An example Container diagram](https://dev-to-uploads.s3.amazonaws.com/i/47cc161teytk608i3w23.png)

## But wait!

Did you spot the two errors in the Container diagram? Let's look at the diagrams next to each other.

![The two diagrams next to each other](https://dev-to-uploads.s3.amazonaws.com/i/mxeynxp8kgb62thng9pw.png)

- "Clinic Employee" has changed to "Clinic Staff".
- The arrow style has changed from dashed to solid.

Granted these are only minor differences, but the problem I want to raise is one of consistency. If you're defining two diagrams in two separate text files, it's easy to make mistakes. Also, perhaps we wanted to change the name of the user from "Clinic Employee" to "Clinic Staff", but perhaps we forgot to change both files or regenerate them both. Some of these problems can be partially solved with the global search and replace tooling we have at our disposal as software developers. And some problems can be solved by integrating the diagram generation process into a CI/CD pipeline. But there's a better way.

## Make models, not diagrams

What we're missing here is a single definition of the elements and relationships across all of our diagrams. When writing code, we often talk about DRY ([Don't repeat yourself](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)), where we try to avoid unnecessary duplication through copy-pasting code. That's exactly how many people create their diagrams though, by copy-pasting diagram definition fragments. PlantUML does support the concept of an [!include directive](https://mrhaki.blogspot.com/2016/12/plantuml-pleasantness-include-partial.html) to include fragments, but this can become complicated.

What we really want to do is create a model of our software architecture, and then visualise it from different angles. The [Structurizr DSL](https://github.com/structurizr/dsl) is an open source project that lets you do just this. Instead of writing two separate PlantUML files, we can define everything in a single file as follows.

```
workspace {

    model {
        clinicEmployee = person "Clinic Employee" "An employee of the clinic"
        springPetClinic = softwareSystem "Spring PetClinic" "Allows employees to view and manage information regarding the veterinarians, the clients, and their pets." {
            webApplication = container "Web Application" "Allows employees to view and manage information regarding the veterinarians, the clients, and their pets." "Java and Spring"
            database = container "Database" "Stores information regarding the veterinarians, the clients, and their pets." "Relational Database Schema"
        }

        clinicEmployee -> webApplication "Uses" "HTTPS"
        webApplication -> database "Reads from and writes to" "JDBC"
    }

    views {
        systemContext springPetClinic {
            include *
        }

        container springPetClinic {
            include *
        }
    }
    
}
```

This text defines a model containing: a user, a software system, two containers, and the relationships between everything. It also then defines two views of this model: one System Context view, and one Container view.

The DSL is a way to define software architecture models and views, but we still need a way to visualise that, and ultimately get some diagrams. We can do this with the [Structurizr CLI](https://github.com/structurizr/cli), another open source project that has a number of features.

```
./structurizr.sh export -workspace spring-petclinic.dsl -format plantuml
```

Running the Structurizr CLI in this way will create two `.puml` files, which we can then render with PlantUML in the normal way.

 ![Example System Context and Container diagrams](https://dev-to-uploads.s3.amazonaws.com/i/a55l6ewgnktvo2tfz8qe.png)

Because both diagrams are created from the same model, they remain in sync, both from a content and a presentation perspective. Changes can now be made to the original DSL source file, and the diagrams regenerated.

## Summary

Creating software architecture diagrams from a textual definition is becoming more popular, but it's easy to introduce inconsistencies into your diagrams if you don't keep the multiple source files in sync. The open source [Structurizr DSL](https://github.com/structurizr/dsl) and [Structurizr CLI](https://github.com/structurizr/cli) can help you create multiple diagrams from the same model.