Skip to main content

Components, Connectors, and Configurations

The core building blocks of systems: components, the connectors between them, and the configurations that shape runtime behavior

What Are Components, Connectors, and Configurations?

In software architecture, system thinking is the practice of viewing a system as a holistic collection of interacting parts. The most fundamental of these parts are components, the connectors that link them, and the configurations that arrange them. Understanding these three elements is the first step toward designing robust, scalable, and maintainable systems.

A system's architecture is defined by its components, how they are connected, and the rules that govern their interaction. This structure dictates the system's capabilities, its quality attributes (like performance and reliability), and how it can evolve over time.

TL;DR

Components encapsulate responsibilities; connectors carry interactions (sync or async); configurations arrange both into a runnable topology. Pick one primary connector per interaction, design for timeouts, retries, and idempotency, and avoid shared databases as an integration mechanism.

Learning objectives

  • You will be able to distinguish components, connectors, and configurations and explain how they interact.
  • You will be able to choose an appropriate connector (REST, gRPC, queue, stream) for a given scenario.
  • You will be able to sketch a configuration that supports independent deployability and observability.
  • You will be able to identify anti-patterns such as shared databases and chatty synchronous calls.

Motivating scenario

Your team is decomposing a growing monolith into a few services: ProductService, OrderService, and a checkout web app. Performance is degraded by chatty HTTP calls and cross-service DB access. By clarifying component boundaries, choosing a single primary connector per interaction, and drawing a clear configuration, you reduce coupling, improve resilience, and make independent deployments safe.

Core Concepts

Components

A component is a deployable unit of computation or a data store—such as a service, database, or message broker. It is modular, independently deployable, and replaceable, encapsulating a set of related functions or data. Components have well-defined interfaces that hide their internal implementation details.

  • Examples: A microservice, a database, a message queue, a client-side web application.

Connectors

A connector is a mechanism that mediates communication, coordination, or cooperation among components. Connectors are the "plumbing" of an architecture, enabling data and control flow. They are distinct from the components themselves and can range from simple procedure calls to complex, network-based protocols.

  • Examples: A REST API call, a gRPC connection, a message bus, an event stream, or a shared memory buffer.

Configurations

A configuration is the structural arrangement of components and connectors. It describes the topology of the system—how the parts are wired together to form a whole. The configuration defines the system's runtime structure and dictates how components interact to fulfill the system's purpose.

  • Examples: A client-server topology, a pipeline of data-processing services, a star-shaped topology with a central message broker.
A simple client–server configuration showing two components (Client, Server) linked by a connector (REST API).

Practical Examples and Real-World Scenarios

Let's consider a simple e-commerce system.

  • Components:
    • ProductService: Manages product information.
    • OrderService: Handles order creation and processing.
    • PostgreSQL DB: A relational database for storing order data.
    • Kafka Topic: An event stream for publishing order events.
  • Connectors:
    • gRPC: Used for synchronous, internal communication between OrderService and ProductService.
    • Postgres Driver: The connector used by OrderService to interact with its database.
    • Kafka Producer/Consumer: The mechanism for writing to and reading from the Order-Events topic.
  • Configuration: The OrderService receives a request, calls the ProductService via gRPC to validate product details, persists the order to its PostgreSQL DB, and publishes an OrderCreated event to a Kafka Topic.
Configuration for an e-commerce system's order processing flow.

Practical Configuration Example

A minimal docker-compose.yml to stand up the components and connectors from the example above.

docker-compose.yml
version: "3.9"
services:
product:
image: ghcr.io/example/product-service:latest
environment:
- GRPC_PORT=50051
ports:
- "50051:50051"

order:
image: ghcr.io/example/order-service:latest
depends_on:
- product
- postgres
- kafka
environment:
- PRODUCT_GRPC_ADDR=product:50051
- DATABASE_URL=postgres://postgres:postgres@postgres:5432/orders?sslmode=disable
- KAFKA_BROKERS=kafka:9092
ports:
- "8080:8080"

postgres:
image: postgres:15
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=orders
ports:
- "5432:5432"

zookeeper:
image: confluentinc/cp-zookeeper:7.6.1
environment:
ZOOKEEPER_CLIENT_PORT: 2181

kafka:
image: confluentinc/cp-kafka:7.6.1
depends_on:
- zookeeper
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
ports:
- "9092:9092"

Decision Model: Choosing the Right Connector

The choice of connector is a critical architectural decision that impacts performance, reliability, and coupling. Use this mental model to guide your selection.

A decision flow for selecting a connector based on communication style and guarantees.

Decision Matrix: Connector Trade-offs

OptionCouplingPerformanceComplexityTypical use
REST APILowMediumLowExternal-facing APIs; simple integrations
gRPCMediumHighMediumInternal service-to-service; low latency
Message QueueVery LowHighMediumAsynchronous tasks; load leveling
Event StreamVery LowVery HighHighEvent sourcing; stream processing
Shared Database (anti-pattern)HighHighLowLegacy monoliths; avoid for integration
Choose connectors by coupling, performance, and complexity

Implementation Notes / Patterns / Pitfalls

Do
  • Define clear, stable interfaces for your components.
  • Choose connectors that match your coupling and performance needs.
  • Isolate components to allow for independent deployment and scaling.
  • Use asynchronous connectors to improve resilience and elasticity.
Don't
  • Do not let components bypass connectors and interact directly (e.g., direct DB access across services).
  • Avoid creating a "distributed monolith" by using synchronous, blocking calls everywhere (see ../../anti-patterns-and-pitfalls/distributed-monolith).
  • Do not share databases between components (services) as it creates high coupling (see ../../anti-patterns-and-pitfalls/shared-database-across-services).
  • Do not build custom connector logic when a standard, off-the-shelf solution exists.

Hands‑on exercise: Map and improve a real flow

  1. Pick one user flow (e.g., create order). Draw its current configuration using a simple Mermaid diagram with components and connectors.
  2. Identify the primary connector per interaction and remove unnecessary chatty calls; consider replacing sync hops with an event or queue where appropriate.
  3. Define timeouts, retries with jitter, and idempotency keys at each connector.
  4. Add basic SLOs (success rate, p95 latency) and instrument logs/metrics/traces at boundaries.

Edge Cases and Failure Modes

  • Timeouts and retries: set per-connector deadlines; prefer exponential backoff with jitter.
  • Partial failures: design idempotent handlers and compensating actions; prefer async where feasible.
  • Duplicate deliveries: ensure consumers are idempotent; use deduplication keys.
  • Thundering herds: apply rate limits and circuit breakers at connector boundaries.
  • Multi-tenant isolation: avoid cross-tenant data leakage; segregate topics/queues and database schemas.

Operational Considerations

  • SLOs/SLIs: Each component should have defined Service Level Objectives (SLOs). For example, the ProductService might have an SLO for 99.9% availability and a 50ms 99th percentile latency. Connector behavior (e.g., retry policies, timeouts) directly impacts these metrics.
  • Rollouts: Components should be independently deployable. A change to the OrderService should not require a redeployment of the ProductService. Use techniques like blue-green or canary deployments to roll out new component versions safely.
  • Quotas/Limits: Implement rate limiting and quotas on component interfaces to prevent cascading failures. A connector like an API Gateway is an ideal place to enforce these policies.

Security, Privacy, and Compliance

  • Authentication & Authorization: Connectors must enforce security. For example, an API Gateway can validate JWTs for external requests, while a service mesh can enforce mTLS for internal gRPC calls.
  • Data Classification: Components handle data of varying sensitivity. Ensure that connectors prevent leakage. For instance, an OrderService should not expose PII through an insecure connector.
  • Secrets Management: Components often need secrets (API keys, credentials) to use connectors. These must be managed securely via a vault, not hardcoded in configurations.

Observability

  • Logs: Components should produce structured logs. Connectors should add correlation IDs to trace requests as they flow through the system.
  • Metrics: Each component should expose key metrics (e.g., request rate, error rate, duration - RED metrics). Connectors can also provide metrics, such as queue length for a message broker.
  • Traces: Use distributed tracing to visualize the entire lifecycle of a request across multiple components and connectors. This is invaluable for debugging performance issues.

Testing

  • Contract tests: verify component interfaces and connector schemas (e.g., CDC/AsyncAPI for events).
  • Resilience tests: inject timeouts, retries, and broker outages; assert graceful degradation.
  • Performance tests: measure latency budgets across connectors; include p99s and saturation.
  • End-to-end tests: cover critical flows across components using synthetic data and correlation IDs.

When to Use / When Not to Use

When to formally define Components, Connectors, and Configurations:

  • When designing a new system from scratch.
  • When decomposing a monolith into microservices.
  • When your system is becoming complex and you need to manage dependencies.
  • When you need to communicate the architecture to new team members.

When this level of formalism might be overkill:

  • For very small, single-purpose applications or scripts.
  • In the early stages of a prototype where speed is more important than structure.

Design Review Checklist

Component & Connector Design Checklist

  • Is the component’s responsibility well-defined and cohesive?
  • Is the component’s interface clear and hiding implementation details?
  • Does the chosen connector match the required performance and reliability?
  • Is the communication pattern (sync/async) appropriate for the use case?
  • Can the component be deployed and scaled independently?
  • Are security controls (authn/authz) enforced by the connector?
  • Is there a clear strategy for versioning the component’s interface?
  • Are observability hooks (logs, metrics, traces) built into the component and connector?
  • Have you avoided shared mutable state between components?

Signals & anti‑signals

When formal components/connectors help vs. add overhead

Multi-team system; independent deployability required; cross‑process boundaries; need for async resilience; regulatory or performance SLOs.
Tiny app; single team; in‑process calls only; throwaway prototype where speed outweighs structure.

Next steps

Self‑check

  1. What distinguishes a component from its connectors?
  2. When would you choose an event stream over a message queue?
  3. Which connector policies most affect your SLOs (and how)?
info

One takeaway: Favor one primary connector per interaction and design it with explicit timeouts, retries, and idempotency.

References

  1. Software Architecture in Practice, 3rd Edition ↗️
  2. SEI: Software Architecture Patterns & Resources ↗️