Skip to content

Component & Integration Design

Component and integration design draws the boxes — the services, databases, and external systems — and decides how the arrows between them actually talk.

  • What it is: Identifying the components (services, databases, external systems) a solution needs and deciding the integration pattern between each pair — a synchronous API call, an asynchronous message, or a batch data transfer.
  • Why it matters: this is the part of the design every downstream team inherits — get the arrows wrong and the pain (cascading failures, tight coupling, unclear ownership) shows up long after launch.
  • For developers: this is the actual architecture diagram you’ll be handed before writing code — if an integration is drawn as a plain arrow with no pattern noted, ask whether it’s meant to be sync or async before you build against it.
  • When to use it: after Non-Functional Requirements are known, since the NFRs often determine which integration pattern is viable.
  • When not to use it: to over-decompose a simple problem into many components “for flexibility” it doesn’t need yet.
  • Prerequisites: a chosen solution option and its NFR targets.
flowchart LR
    A[Web Storefront] -- sync API call --> B[Checkout Service]
    B -- async event --> C[Analytics Store]
    B -- sync call --> D[Payment Gateway]

Each arrow is a deliberate choice, not a default. Synchronous calls are simple but couple the caller to the callee’s availability; asynchronous messaging decouples them at the cost of added complexity (queues, eventual consistency).

  1. List the components the scoped solution needs — existing systems it must touch, and any new ones the chosen option requires.
  2. For each pair of components that need to exchange data, decide: does the caller need an immediate response (sync), or can it continue without waiting (async)?
  3. Check each integration choice against the relevant Non-Functional Requirements — a hard availability target usually rules out tight synchronous coupling to a less-reliable system.
  4. Draw the component diagram with the pattern labeled on each arrow, not just the direction.
  5. Flag any new dependency on a system outside the initiative’s control as an input to Risk & Constraint Management.

A marketing team wants live dashboards of site activity without slowing down the production storefront.

  • Input: a requirement to add real-time analytics to an existing e-commerce platform.
  • Process: querying the production database directly for dashboards would compete with checkout traffic for the same resources, risking the storefront’s own NFRs; instead, the design streams events asynchronously through a message queue to a separate analytics store.
  • Output: the storefront publishes events without waiting for the analytics side to process them; the analytics store and dashboards read from the queue independently, so a slowdown on the analytics side never affects checkout.
  • On Azure, this is typically an Azure Service Bus topic between the storefront and an independent analytics consumer writing to its own Azure Cosmos DB store:
// Storefront: fire-and-forget publish — checkout never waits on the analytics side
await using var client = new ServiceBusClient(connectionString);
ServiceBusSender sender = client.CreateSender("site-activity");
var message = new ServiceBusMessage(JsonSerializer.SerializeToUtf8Bytes(activityEvent))
{
ContentType = "application/json"
};
await sender.SendMessageAsync(message);

Alternative: a serverless consumer. Instead of an always-on Container Apps consumer, the analytics side can be an Azure Function with a Service Bus trigger — useful when the consumer’s workload is bursty and paying for idle capacity isn’t worth it. Martin Fowler’s Serverless Architectures article frames the trade-off: less operational overhead and pay-per-execution cost, at the price of cold-start latency and tighter coupling to the platform’s runtime model.

[Function("ProcessSiteActivity")]
public async Task Run(
[ServiceBusTrigger("site-activity", Connection = "ServiceBusConnection")] string message,
FunctionContext context)
{
var activityEvent = JsonSerializer.Deserialize<SiteActivityEvent>(message);
await _cosmosContainer.UpsertItemAsync(activityEvent, new PartitionKey(activityEvent.SessionId));
}

Choosing between the two isn’t about which is “better” in the abstract — it’s another entry for Technology Selection: an Azure Function is cheaper at low or bursty volume, a Container Apps consumer is cheaper and more predictable at sustained high volume.

Use case When to use Notes
Adding a reporting/analytics feature The new feature shouldn’t affect an existing system’s performance Prefer async streaming over direct production-database queries
Calling an external payment or identity provider The caller needs to know the outcome before continuing Sync call is usually required, but combine with the provider’s SLA in your own NFRs
Connecting two systems owned by different teams Coupling one team’s deploys to another’s availability is a risk Async messaging reduces the blast radius of one side being down
Bursty, unpredictable consumer workload Traffic is spiky rather than steady An Azure Function (consumption plan) avoids paying for idle capacity; an always-on consumer suits steady, high-throughput streams
  • Sync vs. async is a trade-off, not a preference: sync is simpler to reason about but couples availability; async decouples availability at the cost of eventual consistency and operational complexity (queues, retries, dead-letter handling).
  • Label the pattern, not just the arrow: a diagram arrow without a stated pattern (sync/async/batch) leaves the actual behavior to be discovered during implementation.
  • New external dependencies are new risks: every arrow to a system outside the initiative’s control should show up in Risk & Constraint Management.
  • One diagram usually isn’t enough — use separate views: arc42 splits this concern into three distinct views answering three different questions — the Building Block View (static structure: what components exist and how they’re nested), the Runtime View (behavior: the sequence of calls for a specific scenario, like the payment confirmation flow), and the Deployment View (infrastructure: which building block runs on which node). A single “boxes and arrows” diagram that tries to answer all three at once tends to leave out the information a specific stakeholder actually needs.
  • This work spans TOGAF ADM Phases C and D: component identification and data flows correspond to Phase C (Information Systems Architecture — data and application), while the technology and platform choices behind each component correspond to Phase D (Technology Architecture).
Term Meaning
Component A service, database, or system that is a distinct part of the solution
Synchronous (sync) integration The caller waits for a response before continuing
Asynchronous (async) integration The caller continues without waiting; the response (if any) arrives later, often via a queue or event
Eventual consistency Data across components converges to the same state over time, not instantly, as a consequence of async integration
Building Block View / Runtime View / Deployment View arc42’s three structural, behavioral, and infrastructure views of a design — a component diagram is usually a mix of these that’s clearer when split apart
Symptom Likely cause Fix
A new feature slows down an unrelated existing system They share a synchronous dependency (often a database) under new load Move the new feature to an async integration against its own data store
Diagram looks fine but nobody knows if a call is sync or async Integration pattern wasn’t labeled on the arrow Annotate every arrow with its pattern before implementation starts
One team’s outage cascades into another’s Tight synchronous coupling between independently-deployed systems Introduce a queue or async boundary, or add a fallback/circuit breaker
  • Why might querying a production database directly for a new reporting feature be risky?
  • Take an integration you’ve built and decide whether it should have been sync or async, and why.

Part of Introduction to Solution Architecture. Follows Non-Functional Requirements; feeds into Technology Selection and Risk & Constraint Management. See also the Glossary.