- 5 minutes to read

L3 Component Diagram Example

The L3 Component diagram zooms into a single container and reveals its internal modules, classes, and interactions. It is the most detailed diagram in the C4 zoom hierarchy and is intended for developers implementing or maintaining the container.

See Example C4 Diagrams for an overview of all diagram types and when to use each.

To use this example in Nodinite, copy the Mermaid markup below and follow the Creating Your First C4 Diagram import walkthrough to create a Diagram Set, import the markup, and bind nodes to your Repository.

When to Use

  • Onboarding developers to a codebase
  • Documenting the internal structure of a complex service or API
  • Planning refactoring or identifying excessive coupling
  • Not typically shared with non-technical audiences

Example: O2C Portal — Sales Domain Components

This example zooms into the Portal container within the O2C Sales Domain to reveal its internal code-level components — the classes, handlers, and subsystems that implement the order receiving and confirmation flow.

Do not use Nodinite Service names (e.g. INT1337-RCV-Order-Incoming) as Component node labels in an L3 diagram. Those names belong to Nodinite Services, which are L2 binding targets (mapped to Container nodes). If you name an L3 Component node after a Nodinite Service, importing the diagram creates a duplicate entry as an Integration in the Repository — a completely different entity type — resulting in both a Service and an Integration with the same name. L3 Component nodes must represent implementation-level artefacts: controllers, handlers, validators, repositories, and publishers that live inside the container.

The diagram uses the following shape types:

  • Component — application-level handlers and processors (controller, validator, confirmation builder, dispatcher)
  • ComponentDb — the Order Repository (SQL Server persistence layer; using plain Component here would be wrong)
  • ComponentQueue — an async Domain Event Publisher feeding the Planning Event Bus
  • Component_Ext — an external ERP Adapter wrapping the upstream ERP contract
  • ComponentDb_Ext — an external Audit Log Database for compliance records
  • ComponentQueue_Ext — an external event bus for trading partner notifications

The BiRel connector between the Outbound Dispatcher and the ERP Adapter shows the two-way handshake used during order booking confirmation.

Preview Mermaid Code
C4Component title O2C Portal — Sales Domain (L3 Component Diagram) Person(customer, "Customer", "Submits orders and reads confirmations via the Portal") Container_Boundary(portal, "Portal — Sales Domain") { Component(api_handler, "Order API Handler", "ASP.NET Core", "HTTP entry point: authenticates, deserialises, and dispatches inbound order requests") Component(order_validator, "Order Validator", "C# / FluentValidation", "Validates order schema, business rules, and customer identity before processing") Component(dedup_guard, "Deduplication Guard", "C#", "Checks the Order Repository to prevent reprocessing of already-received orders") ComponentDb(order_repo, "Order Repository", "SQL Server", "Persists received orders before forwarding. Supports deduplication and retry-safe processing") Component(outbound_dispatcher, "Outbound Dispatcher", "C# / HTTP Client", "Forwards the validated order to ERP via the ERP Adapter and collects the booking confirmation") Component(confirm_builder, "Confirmation Builder", "C# / CSV Writer", "Assembles the CSV order confirmation and routes it back to the customer") ComponentQueue(event_publisher, "Domain Event Publisher", "AMQP / Azure Service Bus", "Publishes O2C.Order.Received events to the Planning Event Bus asynchronously") } Component_Ext(erp_adapter, "ERP Adapter", "Gateway / C#", "External component wrapping the upstream ERP order-entry API contract") ComponentDb_Ext(audit_log, "Audit Log DB", "External Database / SQL", "External compliance audit store — immutable record of all order state transitions") ComponentQueue_Ext(ext_event_bus, "Trading Partner Event Bus", "External Message Broker", "Downstream event stream consumed by trading partner systems") Rel(customer, api_handler, "Submits order", "HTTPS / JSON") Rel(api_handler, order_validator, "Passes deserialised payload", "In-process") Rel(order_validator, dedup_guard, "Forwards validated order", "In-process") Rel(dedup_guard, order_repo, "Reads and writes order record", "SQL") Rel(dedup_guard, outbound_dispatcher, "Forwards unique order", "In-process") BiRel(outbound_dispatcher, erp_adapter, "Sends order / receives booking confirmation", "REST / HTTPS") Rel(outbound_dispatcher, confirm_builder, "Passes booking confirmation", "In-process") Rel(confirm_builder, customer, "Delivers order confirmation", "CSV / O2C.Order.Confirmation/1.0") Rel(dedup_guard, event_publisher, "Triggers async event after persist", "In-process") Rel(event_publisher, ext_event_bus, "Publishes order event to partners", "AMQP") Rel(api_handler, audit_log, "Records order receipt audit entry", "SQL") Rel(confirm_builder, audit_log, "Records confirmation sent audit entry", "SQL")
C4Component
    title O2C Portal — Sales Domain (L3 Component Diagram)

    Person(customer, "Customer", "Submits orders and reads confirmations via the Portal")

    Container_Boundary(portal, "Portal — Sales Domain") {
        Component(api_handler, "Order API Handler", "ASP.NET Core", "HTTP entry point: authenticates, deserialises, and dispatches inbound order requests")
        Component(order_validator, "Order Validator", "C# / FluentValidation", "Validates order schema, business rules, and customer identity before processing")
        Component(dedup_guard, "Deduplication Guard", "C#", "Checks the Order Repository to prevent reprocessing of already-received orders")
        ComponentDb(order_repo, "Order Repository", "SQL Server", "Persists received orders before forwarding. Supports deduplication and retry-safe processing")
        Component(outbound_dispatcher, "Outbound Dispatcher", "C# / HTTP Client", "Forwards the validated order to ERP via the ERP Adapter and collects the booking confirmation")
        Component(confirm_builder, "Confirmation Builder", "C# / CSV Writer", "Assembles the CSV order confirmation and routes it back to the customer")
        ComponentQueue(event_publisher, "Domain Event Publisher", "AMQP / Azure Service Bus", "Publishes O2C.Order.Received events to the Planning Event Bus asynchronously")
    }

    Component_Ext(erp_adapter, "ERP Adapter", "Gateway / C#", "External component wrapping the upstream ERP order-entry API contract")
    ComponentDb_Ext(audit_log, "Audit Log DB", "External Database / SQL", "External compliance audit store — immutable record of all order state transitions")
    ComponentQueue_Ext(ext_event_bus, "Trading Partner Event Bus", "External Message Broker", "Downstream event stream consumed by trading partner systems")

    Rel(customer, api_handler, "Submits order", "HTTPS / JSON")
    Rel(api_handler, order_validator, "Passes deserialised payload", "In-process")
    Rel(order_validator, dedup_guard, "Forwards validated order", "In-process")
    Rel(dedup_guard, order_repo, "Reads and writes order record", "SQL")
    Rel(dedup_guard, outbound_dispatcher, "Forwards unique order", "In-process")
    BiRel(outbound_dispatcher, erp_adapter, "Sends order / receives booking confirmation", "REST / HTTPS")
    Rel(outbound_dispatcher, confirm_builder, "Passes booking confirmation", "In-process")
    Rel(confirm_builder, customer, "Delivers order confirmation", "CSV / O2C.Order.Confirmation/1.0")
    Rel(dedup_guard, event_publisher, "Triggers async event after persist", "In-process")
    Rel(event_publisher, ext_event_bus, "Publishes order event to partners", "AMQP")
    Rel(api_handler, audit_log, "Records order receipt audit entry", "SQL")
    Rel(confirm_builder, audit_log, "Records confirmation sent audit entry", "SQL")

Shape Coverage

This example exercises the following L3 shape vocabulary from the toolbox plan:

Shape used Macro Notes
Person (internal) Person Customer
Component (generic) Component Order API Handler, Order Validator, Deduplication Guard, Outbound Dispatcher, Confirmation Builder
Component Database ComponentDb Order Repository — correct shape for data-access / persistence components
Component Queue ComponentQueue Domain Event Publisher
Component (external) Component_Ext ERP Adapter
Component Database (external) ComponentDb_Ext Audit Log DB
Component Queue (external) ComponentQueue_Ext Trading Partner Event Bus
Container boundary Container_Boundary Portal — Sales Domain
Bidirectional connector BiRel Outbound Dispatcher ↔ ERP Adapter booking handshake

Common mistake: Do not use Component for repository or data-access shapes. Use ComponentDb instead — this renders the correct database cylinder icon and clearly communicates the shape's role as a data store.

Next Step

See the runtime sequence across all domains with the Dynamic Diagram Example.