C4 Models: Architecture From Simple To Complex
Tags: architecture
Published: 2022-10-07 08:59:44

Software Architect from inDrive Alexander tells about how to define the architecture in a better way and shares his experience in C4 models usage.

## Real life architecture
If you open Wikipedia, you will find there the exact definition of what architecture is. I found out that architecture is the process of creating and drawing certain diagrams, certain buildings, and other structures. People use architecture as a science to simplify complex designs such as bridges or buildings.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3214u8jopodb1guj77xr.png)


In real life, architecture surrounds us everywhere. Even the room you're in right now is part of the architecture. It has windows, doors, and places to sit. And in real life, architecture has many standards. We can rely on standards to define our architecture and share this information with our peers. For example, from building components to who will create this building. The really good part about this architecture is that we can get down to very small details, like how to create this particular wall or how to create this particular room.

## Architecture in IT

### Paper
When it comes to IT, building an application architecture is like building a building. And in the beginning, we, like real architects, used the traditional way of creating architecture - we drew on plain paper. This method is good in that it improves the creativity used to brainstorm changes in our architecture, but at the same time it is very difficult to maintain.

On paper, it is difficult to capture the standards that are extremely important for any architecture. We have many paths displayed as small blocks connected by lines that were not standards at all. When we are going to fit a lot of details into this picture or understand what is going on at one level or another, it is very problematic. Then we replaced the paper with the draw.io tool at the request of the system administrator.

### Draw.io
Draw.io was a nice try. In draw.io, at the beginning, you can draw the desired picture, and then connect the blocks with lines. If we have many components or many connections or relationships between components, then at some point it will be very problematic to set up this diagram. For example, imagine what happens if we want to move a PHP component from a central location to another

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hpv1zmg9vm3opu7ljx1g.png)

If you need to move to a separate data center, it will require a lot of work to update everything. It's very difficult to understand how everything works in general, because we have completed pictures, we have a lot of details and usually we can't present this diagram to non-IT colleagues. If you want to provide this diagram to senior management, obviously they won't understand what's going on in the diagram.

### Miro
Another attempt is better. It's a Miro way, let's say. I like Miro because of very cool zooming feature, which is available by default in Miro. We can drill into our parts and see what's happening inside zooming into particular blocks. It's still partially maintained well because if we want to rearrange some parts or create some new components, then you will be required to draw all new lines, adjust the layout.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1crwwh82widyk01qujhk.png)

I guess it's annoying because, at some point in time, I will spend too much time just connecting small parts with each other. At some point, I guess this process will not be maintainable and require some energy from analysts to keep it up to date. Let's see how we can do it in a more standard way. I'm going to present you with a C4 model. This model was designed to simplify the process of designing architecture by describing the picture.

## C4 Models
On a very high level, we have this software system definition is used to describe systems in general. Then we have several more layers. Usually, we have more layers, which are containers, components, and the last one is code. On each layer we can define our architecture with more details. It's kind of zooming into our architecture. 

### How it works
You can see that we have this context in the very top of the picture. If we click or select our central component which is the system, we can read or zoom into the container level where we can see more details which containers are required to run our application. How containers are connected between each other and what our external system is. On level three, we have an even more detailed picture.

For example, different processes running inside our single container can be producers, subscribers, this can be Google, or something like that. On level four, we can have a well-built picture of a particular component with maybe UML diagrams of processes or database models. Okay, let's check what's happening inside. If we are talking about our first layer, which is system context, we are trying to represent our system as a very big block.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ollpbawfgn5aq3jhw5vy.png)

Usually, blocks are presented to these boxes and we have links between such boxes. Usually, we describe only systems which are part of our application or system context. In this case, we are looking at some banking systems and we have just a mainframe banking system which stores information about customers account transactions, et cetera. We do not specify any database names, types, MySQL or Oracle, etc.

We don't want to have any technical details on this level, just because we want to make this diagram available for everyone. Every person, even non-technical people should understand what's happening in the system. We can see the banking system uses an email system which is external one and just sends email using this system and stores information about payments in the banking system mainframe.

Obviously, we have a customer who uses our systems and calls our API. Next level is more interesting for us, especially in IT. The community is a container diagram and we can see much more details here on this picture. In the diagram, there is information about containers which are required in order to run our application and we can see that now we have details about protocols. We usually use this information to understand what kind of dependencies, and what kind of protocols are used by this particular system.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rh4tk4gw5mph5iftvaeo.png)

C2 levelThis information can help us to understand better requirements of how we can scale our application, how we can deploy this application to a new data center, and this information is most important for us because we have all necessary links, all necessary information about all containers which are required to run the application on this container diagram.

Every container, do not confuse, it's not a docker container, it's a separate application that should be presented on the scheme because we want to understand how every container is connected with our application in order to make it scalable or we can think about how we can protect personal data about our customers. What if we are going on the next level which is C3 and it's a component diagram?

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p7jpx3ga9932b7eimqg2.png)


On this level, we can present even more details compared to component diagrams and we can show internal parts of our application. For example, if you are talking about Go applications this can be a dedicated group of goroutines, consumers for Kafka or producers to Kafka. We can show some specific components like HTTP handle or maybe gRPC handle. We can show different protocols as well on this diagram like HTTPS or gRPC between some parts.

We can show integration between controls itself and we can also present some external systems like an email system which is called by email component and we can present information about a database as well. There is information about type. In this case, we are using Oracle database and this diagram presents all necessary information about all blocks. If we go to the last level which is C4, we can drill up to very low-level details, how our component is working and this can be entity relation diagram, this can be email process or activity diagram.

In the the billing service and we have created order, canceled order, and changed order defines it, and how particular containers or components are connected to each other. What I like in this way of describing architecture is that we can go from the very high definition of our application up to very low-level details which is really important in order to make our diagrams easy to read, easy to follow, and here is our current process.

We have this inDrive architecture docs repository and currently, I'm trying to create C1 and C2 levels of all our components, and probably you have already checked it. You can claim it, you can use it with ideas, you can install the PlantUML plugin for your idea and just navigate through all components in real-time by clicking on components and you will drill down from the system context diagram up to internal details.