Microservices Architecture Guide: Patterns and Best Practices

API7.ai

July 13, 2026

Technology

Introduction

Microservices architecture organizes an application as independently deployable services aligned with business capabilities. Each service owns a focused responsibility, exposes a defined interface, and can evolve without requiring every other part of the system to be released at the same time. The API infrastructure guide explains the gateway, management, governance, and observability capabilities that make this model operable.

That flexibility has a cost. A method call inside a monolith becomes a network request or message. Data consistency becomes a distributed-systems concern. Teams need service discovery, traffic management, observability, security, deployment automation, and clear ownership. Microservices are therefore an organizational and operational architecture, not simply a way to split source code into smaller repositories. See API observability and platform engineering for the cross-cutting practices behind that operating model.

This guide is for software architects, backend developers, platform engineers, and engineering leaders. It explains when microservices are appropriate, how to define service boundaries, how services communicate, where API gateways and service meshes fit, and how to migrate incrementally without creating a distributed monolith. It should be read alongside the broader API infrastructure learning path.

What Are Microservices?

A microservice is an independently deployable application component that implements a cohesive business capability and communicates through an explicit contract. A microservices system is the collection of those services plus the platform capabilities required to operate them.

Common characteristics include:

  • Services are aligned with business capabilities or bounded contexts rather than technical layers.
  • Each service has a clear owner and deployment lifecycle.
  • Interfaces are explicit, versioned, and observable.
  • Services can be scaled and changed independently when the business need justifies it.
  • Data ownership is decentralized; other services use contracts rather than reading another service's database directly.
  • Automation handles build, test, deployment, configuration, and telemetry consistently.

Microservices do not require every service to be tiny. The useful boundary is one that reduces coordination while keeping the service understandable and operable. Read Microservices and APIs: Designing Modular Applications for a foundational overview.

When Microservices Are and Are Not Appropriate

Microservices can help when a system has multiple teams, independently changing domains, different scaling characteristics, strict isolation needs, or a release process constrained by a large shared deployment. They can also support gradual modernization when a stable boundary can be extracted from a monolith. For the migration dimension, compare this decision with the Kubernetes migration guide and its platform-readiness guidance.

They are not automatically the best starting point. A modular monolith is often more efficient when:

  • The product and domain boundaries are still changing rapidly.
  • One small team owns the entire application.
  • Independent deployment and scaling provide little practical value.
  • The organization lacks reliable deployment, observability, and incident-response practices.
  • Strong transactions across many modules are central to the workload.

The decision should compare business outcomes and operating cost. Microservices introduce network latency, partial failure, eventual consistency, cross-service testing, more infrastructure, and more production ownership. Use them where those costs buy meaningful team or system autonomy.

Service Boundaries and Data Ownership

Service boundaries are the most consequential design decision. Splitting by technical layer, such as separate services for controllers, business logic, and persistence, increases network coupling without creating business autonomy. Prefer boundaries based on business capabilities, domain subdomains, ownership, change patterns, and data responsibility. Consistent contracts and ownership also connect this topic to API governance and API management.

flowchart LR
  clients[Web, Mobile, and Partners] --> gateway[API Gateway]
  gateway --> catalog[Catalog Service]
  gateway --> orders[Order Service]
  gateway --> accounts[Account Service]
  orders --> events[Event or Message Broker]
  catalog --> catalogdb[(Catalog Data)]
  orders --> orderdb[(Order Data)]
  accounts --> accountdb[(Account Data)]
  events --> fulfillment[Fulfillment Service]

Design Around Cohesion

A service should contain behavior and data that change together. If two services must always be deployed together or coordinate synchronously for every operation, the boundary may be too fine. If one service contains unrelated capabilities owned by different teams, it may be too broad.

Own Data Through APIs and Events

Shared databases create hidden coupling. A schema change by one team can break another team's queries, and ownership becomes ambiguous. Prefer service-owned data with access through APIs or events. This does not require a separate database server for every service, but logical ownership and change control must be clear.

Plan for Consistency

Cross-service workflows cannot assume one local database transaction. Common approaches include sagas, transactional outbox patterns, idempotent consumers, and compensating actions. The right approach depends on whether the business process can tolerate temporary inconsistency and how failures should be repaired.

Microservices Communication Patterns

Services communicate synchronously, asynchronously, or through a deliberate combination. The right choice depends on latency, coupling, delivery guarantees, failure handling, and the consumer contract; the gateway is one part of that communication design, not a replacement for service-to-service decisions.

Synchronous Request-Response

HTTP APIs, gRPC, and other request-response protocols are useful when a caller needs an immediate result. They are easy to reason about locally, but they create runtime dependency: the caller's latency and availability now depend on the callee.

Use explicit timeouts, bounded retries, circuit breakers, and request budgets. Avoid deep synchronous call chains where one user request must pass through many services before completing.

Asynchronous Messaging and Events

Queues and event streams decouple producers from consumers in time. They support background work, fan-out, integration, and resilient workflows. They also introduce delivery semantics, ordering, idempotency, schema evolution, and operational lag.

Events should represent meaningful state changes, not expose an internal database log without a contract. Consumers must handle duplicates and delayed messages. See Async APIs and Microservices for the relationship between asynchronous systems and API gateways.

API Composition and Orchestration

Clients should not need to understand every internal service. An API gateway or composition service can combine data and coordinate calls for a specific client experience. Orchestration can simplify consumers, but overly centralized workflow logic can become a new monolith. Read What Is API Orchestration? for the trade-offs.

Service Discovery and Load Balancing

Service instances are dynamic in virtualized and containerized environments. They scale, restart, and receive new addresses. Discovery connects a stable service identity to healthy instances, which is also a core concern when services move to Kubernetes.

Client-side discovery lets the caller query a registry and select an instance. Server-side discovery sends requests to a router or load balancer that resolves the destination. Kubernetes Services provide a platform-level form of server-side discovery for workloads in a cluster.

A discovery design should answer:

  • Who registers and removes instances?
  • How is health determined?
  • How quickly do changes propagate?
  • Which load-balancing policy is used?
  • What happens when the registry or control plane is unavailable?
  • How are services discovered across clusters or environments?

For implementation examples, read API Gateway and Service Discovery and Integrating Service Discovery with API7 Enterprise.

API Gateway vs Service Mesh

An API gateway and a service mesh address different traffic boundaries.

ConcernAPI GatewayService Mesh
Primary trafficClient-to-service, or north-southService-to-service, or east-west
Consumer identityUsers, applications, partnersWorkloads and services
API product policiesAuthentication, quotas, transformations, versionsUsually not the primary responsibility
Service communicationRoutes to upstream servicesManages service-to-service connectivity
Deployment modelShared or distributed gateway data planesProxies or node-level data plane within the service environment
Typical ownersAPI platform and edge teamsPlatform, networking, or service platform teams

The API Gateway Guide explains the external runtime layer. API Gateway vs Service Mesh provides a detailed comparison. Many systems use both: the gateway controls consumer-facing APIs, while the mesh supports workload identity, encryption, routing, and telemetry inside the service environment.

flowchart LR
  consumer[External Consumers] --> gateway[API Gateway]
  gateway --> serviceA[Service A]
  subgraph mesh[Service-to-Service Layer]
    serviceA <--> serviceB[Service B]
    serviceB <--> serviceC[Service C]
  end
  platform[Shared Identity, Policy, and Telemetry] --> gateway
  platform --> mesh

Resilience, Security, and Observability

Design for Partial Failure

Networks fail, dependencies slow down, and instances disappear. Set timeouts based on end-to-end latency budgets. Retry only operations that are safe to repeat, add jitter and limits, and avoid retry storms. Circuit breakers, bulkheads, queues, and load shedding prevent one failure from consuming the entire system.

Establish Service Identity and Access

External identity is often validated at the gateway, but services still need authorization for domain actions. Service-to-service communication may use workload identity and mTLS. Propagate only the claims a service needs, protect credentials, and avoid treating the internal network as trusted. See Deep Dive into Authentication in Microservices and the API Security Guide.

Correlate Telemetry Across Services

Metrics, structured logs, and distributed traces need shared service names, trace context, deployment metadata, and ownership. Monitor consumer-facing latency and errors at the gateway, then follow traces into services and dependencies. The API Observability Guide provides the complete telemetry model; Monitoring Microservices with Prometheus and Grafana offers an implementation example.

Monolith-to-Microservices Migration

Migration should reduce risk and improve delivery, not maximize service count.

  1. Strengthen the monolith first. Define modules, ownership, tests, observability, and deployment automation.
  2. Map business capabilities and change pressure. Identify domains constrained by scaling, release coordination, or ownership.
  3. Select a low-risk boundary. Start with a capability that has a clear contract and limited transactional coupling.
  4. Create a routing seam. Use an API gateway or facade so traffic can move between old and new implementations without changing every client.
  5. Move behavior and data deliberately. Establish ownership, synchronization, cutover, and rollback plans.
  6. Measure the outcome. Compare deployment frequency, reliability, latency, cost, and team coordination before extracting more services.

The strangler pattern routes selected capabilities to new services while the monolith continues to handle the remainder. Avoid a big-bang rewrite. If the target environment is Kubernetes, continue with the Kubernetes Migration Guide.

Microservices Best Practices

  • Align services with business capabilities and team ownership.
  • Prefer a larger cohesive service over many tightly coupled small services.
  • Define contracts, compatibility rules, and deprecation policies.
  • Keep data ownership explicit and avoid cross-service database access.
  • Choose synchronous or asynchronous communication according to the workflow.
  • Set timeouts, retry budgets, circuit breakers, and backpressure deliberately.
  • Automate builds, tests, security policy, deployment, and rollback.
  • Standardize telemetry and propagate correlation context.
  • Provide shared platform capabilities without hiding essential operational context.
  • Measure whether the architecture improves delivery and reliability.

Microservices Learning Paths

Foundations and Boundaries

Traffic and Communication

Operations

How API7 and Apache APISIX Fit

Apache APISIX can provide the north-south API gateway layer for microservices, including dynamic routing, authentication, traffic control, service discovery integrations, canary traffic, and telemetry plugins. It does not define service boundaries or replace application-level resilience and authorization.

API7 Enterprise adds centralized gateway and API management for teams operating multiple services, clusters, and environments. It can provide a stable traffic seam during migration and a shared policy layer after services are distributed.

Use the gateway to reduce repeated edge concerns while keeping domain behavior inside services. The architecture succeeds when platform capabilities support service ownership rather than obscuring it.

Tags: