A microservice is an independently deployable business boundary — not a CRUD per table. Prefer the smallest number of services that preserves autonomy and clarity.
For implementation: golang-microservices, nestjs-microservices, rust-microservices. HTTP contracts: api-design. Go-live: production-readiness. Consolidate before distributing: modular-monolith. Contexts: ddd. Events: event-driven-architecture. Decision: software-architecture.
When (not) to use
It makes sense when: autonomous teams, distinct scales, different release cycles, isolatable failures.
Avoid when: uncertain domain, small team, strong latency between “services”, operations without observability. Start modular in the monolith (modular-monolith) and extract with evidence.
Bounded contexts
- One service = one context with its own ubiquitous language.
- Stable public API; private internal model.
- Forbidden: two services sharing the same write database.
- Avoid “distributed monolith”: cascading synchronous calls for every write.
Communication
| Style | Use |
|---|---|
| HTTP/gRPC sync | Queries, commands that need an immediate response |
| Messaging (queue/bus) | Domain events, decouple writers |
| Outbox / inbox | Publish events reliably with the same local transaction |
Rules:
- Timeouts, retries with backoff/jitter, and idempotency on every client.
- Circuit breaker / bulkhead where a downstream failure brings down the product.
- Versioned contracts (
v1, schema registry for events). - Correlation / trace id at all edges.
- Do not invent internal RPC without service-to-service authentication.
Data and consistency
- Database per service (schema or instance).
- Eventual consistency between contexts; document the mental model.
- Sagas/process managers for multi-service workflows; avoid distributed 2PC.
- Composite reads: BFF, materialized view, or explicit orchestration — not HTTP N+1 on the mobile client.
- Data migrations between services: dual-write only with a plan and metrics.
Topology
Client → Gateway/BFF → Serviços → (DB | Queue | Cache)
↘ workers / consumers
- Gateway: edge auth, rate limit, routing — minimal business logic.
- BFF when channels (web/mobile) need different aggregation.
- Sidecars/mesh only if the platform already operates that; do not add complexity early.
Observability and operations
- Structured logs + distributed tracing + RED/USE metrics.
- Health
/liveand/readyper service. - SLOs and alerts per critical service, not just CPU.
- Independent deploy with rollback; feature flags for risky changes.
- Tested contracts (pact/contract or integration suite at the edge).
Security
- Internal zero trust: mTLS or service-to-service tokens.
- Authz in the service that owns the resource (not only at the gateway).
- Secrets in vault/env; no credentials in images.
- Blast radius: least privilege in IAM/network/queues.
Anti-patterns
- Service per CRUD entity (“UserService”, “OrderItemService” without context)
- Shared DB and cross-service joins
- Chatty sync without cache/aggregation
- Events that are just coupled “asynchronous RPC”
- Premature distribution without a stable domain
Completion criteria
- Service boundaries aligned with the domain, not with tech
- Communication, timeouts and idempotency defined
- Data without a shared write DB
- Observability and health per service
- Trade-off vs monolith/modular documented when relevant