Top 5 diagrams for documenting software architecture
A revamp of an old article on the most useful diagrams to document software architecture and tools to create them.
The most difficult aspect of running engineering teams is aligning how we do things. Documenting Software Architecture facilitates the conversations on the approaches, tools and principles we apply to our product. In this article I share the top 5 diagrams I use almost every day: C4 Context and Container diagrams, Deployment Diagram, Sequence diagram and Use Case diagram. Let's go through them.
Context
The c4 website does a pretty good job explaining their diagrams, but I still would like to provide my own understanding.
Your system operates in some context. Primarily, it's their users and other software systems. Users may have different roles like content creator, reader, administrator. Also they can be internal or external. Other software systems may be source of data for your system, or get the information from it. It is important to understand this context to properly design the system and remind yourself to integrate with external systems.
How to draw
Identify the persons who will use your system
Identify the external systems
Create a single rectangle depicting your system
Add connections between the system, users and external systems
Provide meaningful comments on every component
Tools
There are different tools you can use to create the context diagram. There are C4 stencils for OmniGraffle, C4 examples for LucidChart, draw.io has the stencils as well. You can also use PlantUML to leverage diagrams as code. Let's say we want to draw the aforementioned diagram for a neo-banking digital platform with uml:
@startuml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/C4_Context.puml
' uncomment the following line and comment the first to use locally
' !include C4_Context.puml
Person(customer, "Customer", "A bank client")
System(abc_system, "Digital Platform", "Allows freelancers and business owners see their transactions.")
System_Ext(idnow, "IDNow", "System for KYC and Qualified Eletronic Signatures")
System_Ext(pay, "Google Pay/Apple Pay", "Google Pay and Apple Pay systems")
System_Ext(dms, "DMS", "Document Management System")
System_Ext(crm, "CRM", "CRM")
System_Ext(current, "Existing Banking System", "Banking Backoffice")
Rel(abc_system, pay, "uses")
Rel(customer, abc_system, "Uses")
Rel_L(abc_system, idnow, "integrates")
Rel_Neighbor(abc_system, dms, "uploads files")
Rel_D(abc_system, crm, "integrates")
Rel_U(abc_system, current, "uses")
@enduml
We define a person, a system, external systems and the relations between them. Person, System and System_ext predicates have 3 parameters: a key, a title and a description. Rel predicate has 3 parameters as well, but they are different: a key of one entity, a key of another and a name of the relation.
Basically you can draw a context diagram in any drawing tool you'd like. Several great examples can be found here.
Important highlights
Context diagram is the first thing you create when working on a system. Failing to do so may cost you missed integrations and mistakes during system design.
Context may actually include some lower level details, this is perfectly fine.
I was struggling with a context diagram for one banking system. It would include only a newly created system and a single customer, which didn't bring any value. After the reconcideration I added an API Gateway and an existing Auth Provider we were going to use. That way the context diagram started to make sense and allowed to omit those elements from the lower level diagrams.
- Aleksey, Solution Architect.
We had a learning system in development. At the time of Alpha release we understood, that analytical system is not receiving the data from the client facing app. Should we have a context diagram in place, we won't make that mistake. Luckily, it was easy to fix.
- John, Solution Architect.
Summary.
Context diagram is a crucial view which provides the highest level understanding on the people and systems your future system will interact with.
Containers
Containers don't mean docker containers here. Container is an any deployable entity or data storage from the C4 perspective. It can be a mobile application, a website, a VM, a docker container, a database or an object storage; whatever you can deploy. In my experience this diagram is the most complex and it gains the most attention in the same time. That mean it is almost the main diagram you have to work on!
The trick here is you are zooming in into your system. What was a single rectangle, now consists of some rectangles and arrows. Those rectangles are containers now.
Identify the list of entities: microservices, storages, external services
Place them on the diagram
Add comments on the purpose of each component and the technology it is implemented with
Add connections with arrows
Add meaningful labels to each arrow
Pick up a color scheme and apply it
Create a legend.
Tools
Same as for the context diagram: Draw.io, OmniGraffle, LucidChart and others.
Important highlights
Pay attention that the elements are placed in columns. First column is just an API Gateway, the second - the first group of services, then a second group of services, then some storages. This way you demonstrate the layered architecture, which helps to understand the boundaries and responsibilities.
When microservices count grows beyong a single digit, your connection lines will start to intercept. The academical books say you have to avoid the interceptions for readability. Unfortunately, this is not always possible. Do not get upset: focus on making the diagram readable. You can use different colors or line widths, or different line styles(dotted, solid, etc.)
If you use a custom tool(like I am) you need to include a Legend block. It's not obvious what the arrows mean, and what is the color's meaning. Legend explains it.
The common question when using cloud is: do you include the managed services, like queues and messaging solutions? I tend to answer no. This complicates the diagram instead of making it easier to read. If some services are communicating through a message queue, display it via separate type of arrow.
I teach my fellow architects to follow the layered approach when they create container or components-and-connections diagrams. Those diagrams tend to include many entities and structuring them with layers increases readability.
- Ilya, Enterprise Architect.
Summary
Container diagram provides insight into which deployable items your backend consist of and how those components talk to each other.
Sequence Diagram
The first two diagrams show how the elements of the system relate to each other. However, they can not demonstrate what happens in your system. For example, a user sign ups for your system. Which components are involved? What actions are triggered? How the components interact with each other? Sequence diagram can answer these questions.
How to draw
Choose a business case(a user sign-in, a purchase, etc.)
Identify the entities involved in the use case
Put them on the diagram
Add interactions(arrows)
Provide valuable comments to each arrow
Tools
Unfortunately, OmniGraffle is not suitable for sequence diagrams. Therefore I use draw.io and LucidChart for drawing them. The latter is a good choice because you can choose either to draw the diagram manually or use the UML Sequence diagramming. This is possible as Sequence Diagram is a structured one.
Important highlights
Sequence diagram is an absolute must when designing a new feature you add to the system. It shows the affected parts of the system, points of integrations with external software and contracts which the team will have to create or update.
Sequence diagram is valuable for QA engineers as well. It provides the insights where the potential issues can be located and serve as a source of truth for Test Cases.
Few months in a project, and we still faced the issues when the parts of the system were not ready for a long awaited feature. Stakeholders were not happy at all, and there was a traction between different teams. We discussed the issue and agreed to make architecture design before the imlementation. Sequence diagrams were a great help: now we know the full picture before writing the code, not after.
Vladimir, Solution Architect
Summary
Sequence diagrams allow to document the behavior of the system in different business cases.
Deployment Diagram
Using context, containers and sequence diagrams you can answer what parts of the system consist of and how they relate and interact with each others. But they hardly can answer the questions of availability, scalability and security. Deployment diagram helps with that.
There are several different things you want to display.
Compute resources. This can include virtual machines, docker containers, kubernetes clusters and cloud functions. You can also think of mobile devices and desktop computers as compute resources as well.
Storages. Persistent storages for your data like relational and nosql databases, binary file storages like images, music and video, bigdata storages with parket files and so on.
Messaging resources. Kafka/RabbitMQ installations, Google Cloud pub/sub, AWS SQS and others.
Networks. Your computers use networks to communicate with each others. Both physical and virtual networks should be displayed.
Availability Zones. You can think of them as data centers.
Infrastructure Nodes. DNS servers, Load Balancers, Firewalls, CDNs
The diagram shows the compute, storage and messaging resources alongside with networks and availability zones. It also includes the instrastructure nodes which are not fulfilling any functional requirements, but addressing non-functional instead.
How to draw
Place the major building blocks: browsers, mobile devices, public cloud, data centers
Place the computing and storage resources
Add infrastructure nodes
Add networks
Add the network calls between nodes
Add the monitoring resources
Add scalability comments if required
Another example for AWS cloud:
Deployment diagram complements the understanding of the system from the physical appearence perspective.
Use Case Diagram
The most of previous diagrams were very technical ones. Use Case diagram is more business oriented. It depicts how the persons are interacting with your system in a very high level way. Use cases themselves can be treated as business capabilities, which I were describing in this article.
How to draw
Draw a rectange. This will be our System boundary
Define which persons your system is dealing with
Add use cases inside the system using ovals
Add connections between the actors and use cases
Example
Tools
The architect can draw a diagram with any graphical editor and with the same toolset used for other diagrams. Omnigraffle, LucidChart, Draw.io are working well. Remember, that Use Case Diagram is a structured once so you can use UML for creating it. PlantUml or LucidChart helps with that.
Summary
Use context diagram to show the highest level view on the system
Document the use cases with the corresponding diagram
Zoom on the system internals with containers and deployment diagrams
Document particular business cases with sequence diagrams
Discuss this article on twitter.