Mastering Level 2 System Architecture: The Container Diagram in VPasCode
In the realm of software architecture, the Container Diagram (Level 2 in the C4 model) is the bridge between high-level system abstraction and low-level code implementation. It answers the critical question: “How is this system actually built?” While a Level 1 System Context Diagram tells you who uses your system, the Container Diagram reveals the technological heart beating within the system’s boundaries.
This tutorial guides you through the nuances of creating a robust Container Diagram using VPasCode, specifically focusing on the “Order Processing Platform” example shown in the interface. We will explore how to define technology stacks, manage external dependencies, and visualize data flows using PlantUML syntax.
1. The Concept: What is a Container?
In the context of the C4 model and VPasCode, a Container is not necessarily a Docker container, although that is a common implementation. Instead, a container represents a separately useful or independently deployable part of the system. Think of it as a distinct application or service that has its own codebase and runtime environment.
Common examples include:
- Web Applications: Typically built with frameworks like React, Angular, or Vue.js.
- Mobile Applications: Native iOS or Android apps.
- Backend Services: Java Spring Boot microservices, .NET Core APIs, or Python Django apps.
- Databases: PostgreSQL, MongoDB, or Redis instances.
2. Anatomy of the VPasCode Container Diagram
Looking at the provided screenshot, we see a “Order Processing Platform” system boundary. Inside this boundary, the system is decomposed into logical units. Let’s break down the key elements visible in the diagram:
External Actors (Person)
On the left, we see the Customer and the Operations Administrator. These are the people interacting with the system. The lines connecting them to the Web Application indicate that they access the system via a browser or client interface.
The Application Layer (Containers)
The core of the system is broken down into specific services:
- Web Application (React): The frontend interface. It exposes APIs and provides the UI for users.
- Order API (Java / Spring Boot): A backend service that handles the business logic for products and orders.
- Order Processing Worker (Java / Spring Boot): A background service that consumes events (likely from a message broker) to process orders asynchronously.
External Systems
Every modern application relies on external services. The diagram correctly identifies these as SystemExt:
- Catalog Service: Provides product data.
- Event Bus: Handles asynchronous messaging (Kafka).
- Identity Provider: Handles authentication (OAuth 2.0 / OIDC).
- Payment Gateway: Processes financial transactions.
3. Writing the Diagram with VPasCode
VPasCode allows you to generate these diagrams using a declarative syntax based on PlantUML. The code you see on the left panel of the screenshot is the source of truth for the visual representation on the right.
To replicate or build upon this structure, you need to understand the specific directives used:
- Imports: You must include the C4 standard library to access the specialized syntax for containers and relationships.
- Layout: The
LAYOUTLEFTRIGHT()directive ensures the diagram flows logically from left to right, which is standard for C4 diagrams. - Definitions: You define your actors, containers, and external systems using specific keywords like
Person,Container, andSystemExt. - Boundaries: The
System_Boundarygroups your internal containers together.
Code Structure Example
Here is how the code in the screenshot translates to the visual model. Note the specific syntax for defining relationships and protocols:
@startuml C4_Container
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
LAYOUT_LEFT_RIGHT()
title Container Diagram - Order Processing Platform
' Define External Actors
Person(customer, "Customer", "Places orders and tracks delivery status")
Person(admin, "Operations Administrator", "Manages products, orders, refunds, and reports")
' Define External Systems
System_Ext(identity, "Identity Provider", "OAuth 2.0 / OIDC authentication")
System_Ext(payment, "Payment Gateway", "External payment authorization and capture")
' Define System Boundary and Containers
System_Boundary(orderBoundary, "Order Processing Platform") {
Container(webApp, "Web Application", "React", "Provides the customer and administrator user interfaces")
Container(orderApi, "Order API", "Java / Spring Boot", "Exposes APIs for products, checkout, orders, refunds, and tracking")
Container(worker, "Order Processing Worker", "Java / Spring Boot", "Processes order events and coordinates payment, inventory, and fulfillment")
}
' Define Relationships
webApp --> orderApi : Calls application APIs [JSON/HTTPS]
webApp --> identity : Authenticates users [OAuth 2.0 / OIDC]
orderApi --> orderApi : Publishes order commands and events [Kafka protocol]
worker --> orderApi : Reads and writes orders [JDBC]
4. Advanced Features: Technology and Protocols
One of the most powerful aspects of the Container Diagram is the ability to specify technology tags and protocol labels. This helps developers and stakeholders quickly understand the architecture’s stack.
In the screenshot, look closely at the lines connecting the Order API and the Order Processing Worker. The label reads “Publishes order commands and events [Kafka protocol]”. This implies an event-driven architecture where services communicate asynchronously via a message broker like Apache Kafka.
Similarly, the connection to the Identity Provider explicitly mentions “OAuth 2.0 / OIDC authentication”. This is crucial for security auditing, as it confirms the system uses industry-standard protocols for identity management.
Specifying Technology Stacks
When defining a container in VPasCode, you can append the technology stack in parentheses. For example:
Container(orderApi, "Order API", "Java / Spring Boot", "Exposes APIs for products...")
VPasCode will automatically render this technology tag on the container box, making the diagram self-documenting.
5. Best Practices for Container Diagrams
To ensure your VPasCode diagrams remain maintainable and useful, follow these architectural modeling guidelines:
- Keep it High-Level: A container diagram should show 5 to 10 containers. If you have more than 15, you likely need to split your system into sub-systems or use a Level 3 (Component) diagram for specific complex services.
- Focus on Data Flow: Do not clutter the diagram with every single method call. Only show high-level data flows and interactions (e.g., HTTP, gRPC, JDBC, Kafka).
- Use Standard Libraries: Always use the official C4 PlantUML library includes to ensure your diagrams are compatible with other tools in the ecosystem.
6. Conclusion
The Container Diagram is an essential artifact for bridging the gap between business requirements and technical implementation. By using VPasCode and the C4-PlantUML syntax, you can generate these diagrams as code, ensuring they are version-controlled, consistent, and easy to update as your system evolves.
Whether you are designing a monolithic application or a complex microservices architecture, mastering the Level 2 diagram will help you communicate the system’s structure clearly to your team and stakeholders.