
Introduction to Diagram-as-Code
In modern software development, documentation often falls behind implementation. However, tools like VPasCode by Visual Paradigm bridge this gap by allowing developers to write diagrams directly in code. This approach, known as “Diagram-as-Code,” ensures that your architectural visualizations stay perfectly synchronized with your actual system logic.
Today, we will walk through a practical example of modeling a robust backend service for an application built on .NET 8. By looking at the specific components and their interactions, we can understand how to structure a clean, maintainable architecture.
The Entry Point: API Gateway
Every request in a distributed system typically begins at a central point. In our diagram, we see the API Gateway, implemented here using Kong. This component acts as the traffic cop for our entire service.
- Role: It is responsible for routing incoming traffic.
- Relationship: Notice the arrow labeled “Passes request.” The gateway does not process the business logic itself; it simply directs the flow toward the next layer, ensuring only valid requests enter the internal network.
The Security Layer: Auth Middleware
Before any data reaches the core application, security must be established. This is handled by the Auth Middleware.
In a .NET environment, middleware runs in a pipeline. Here, its specific job is twofold:
- Validates JWT (JSON Web Tokens): It checks if the user sending the request is who they claim to be.
- Extracts User Context: Once validated, it pulls out essential user information (like IDs or roles) to attach to the request object.
If the token is invalid, the request stops here. If successful, the middleware forwards the authenticated request down the line.
The Controller: REST Endpoints
Once the request is secure, it lands in the AccountController. This component represents the ASP.NET API surface of our application.
This is where the public-facing logic lives. It defines the REST endpoints—for instance, routes that handle operations related to “/accounts”. The controller’s primary responsibility is to interpret these HTTP requests and translate them into calls to the underlying business logic. It acts as a thin wrapper, keeping the complex rules away from the web interface.
The Core Logic: AccountDomainService
The heart of any well-architected application lies in its domain layer. In our diagram, this is represented by the AccountDomainService.
This component encapsulates the critical business rules. Looking at the description within the box, we see tasks such as “Balance calc” and “transfer rules.” This separation is vital because:
- Independence: The domain logic shouldn’t care if it’s being called via a web API, a background job, or a command-line tool.
- Maintainability: By isolating transfer rules and balance calculations here, you ensure that changing a rule doesn’t require rewriting the API endpoints.
Beyond the View: Data and Events
While the main vertical flow handles the request/response cycle, the code snippet on the left reveals additional layers of complexity managed by the architecture:
- Data Access: The
AccountRepositoryinteracts with Entity Framework Core (EF Core) to execute SQL queries, handling persistence without cluttering the domain service. - Event Publishing: Using MassTransit, the system publishes events like
TransactionCompletedto a RabbitMQ queue. This decouples services, allowing other parts of the system to react to account changes asynchronously.
Summary
By utilizing VPasCode to visualize this .NET 8 architecture, we gain immediate clarity on how responsibilities are separated. We moved logically from the API Gateway (routing) to the Auth Middleware (security), then to the Controller (interface), and finally to the Domain Service (business logic).
This layered approach ensures scalability and testability. Whether you are drawing this manually or generating it from code, understanding these distinct roles is fundamental to building reliable enterprise-grade applications.




