Skip to content

Article Review: Group 5 — Architecture Meta (Design Patterns & ADRs/RFCs)

Articles Reviewed

  1. 10 Microservices Design Patterns for Developers — Capital One Tech — Overview of 10 foundational microservices patterns
  2. ADRs and RFCs: Their Differences and Templates — Candost Dagdeviren — When to use ADRs vs RFCs, with templates

Key Concepts

Microservices Design Patterns (Capital One)

The 10 patterns and how they map to NGE:

# Pattern Description NGE Status
1 Database per Service Each service owns its database We use this — per-case schema isolation (ADR-003)
2 Saga Distributed transactions via choreography or orchestration Partial — our pipeline is fire-and-forget, not transactional. Needed for ADR-005 (bulk ops)
3 API Gateway Single entry point, routing, auth, SSL Rails serves this — ProcessorApi is the gateway to NGE modules
4 Aggregator Collects data from multiple services, returns combined result PSM does this — aggregates events via Athena for batch status
5 Circuit Breaker Prevents cascading failures with open/closed/half-open states Documented but not implemented — we have the pattern doc but no production circuit breakers
6 CQRS Separate read/write models Not used — our modules do both read and write. Could benefit search (ADR-008)
7 Async Messaging Event-driven communication via message queues Core pattern — SNS/SQS is our primary communication mechanism (ADR-001)
8 Event Sourcing Capture all state changes as events PSM approximates this — all events captured in S3/Athena, but not used to reconstruct state
9 Strangler Incrementally migrate monolith to microservices This IS our strategy — NGE modules strangle legacy Rails functionality case by case via nge_enabled?
10 Decomposition Break monolith by business capability, subdomain, or transaction By business capability — our modules map to EDRM stages (extract, load, upload, export, exchange)

ADRs vs RFCs (Candost)

Key distinction: - ADR = record a decision already made (or being made by a small team). Short feedback period, consent-based ("any strong objections?"), stays close to codebase. - RFC = request feedback before making a decision. Longer process, consensus-based, for significant changes that impact others.

Natural sequence: RFC first (for significant changes) → ADR(s) for implementation decisions

When to use which: - Change affects others / needs buy-in → RFC - Small change, significant impact → RFC - Team decided together, no external impact → ADR - Recording a past decision → ADR

ADR template essentials: Status, Context/Problem, Decision & Rationale, Consequences, Considered Options, Update Log

RFC template essentials: Status, Need/Problem, Approach, Pros/Cons, Alternatives, Update Log

Mapping to NGE Architecture

What We Do Right

1. VALIDATED: Strangler Pattern Is Our Migration Strategy

Our nge_enabled? per-case flag is textbook strangler: new cases use NGE modules, legacy cases continue on Rails workers. Each module (documentloader, documentextractor, etc.) strangles a specific piece of Rails functionality. The monolith never gets rewritten wholesale — it gets incrementally replaced.

2. VALIDATED: Database per Service via Per-Case Schemas

ADR-003 gives each module its own database context (per-case schemas). No module can access another module's data except through SNS events. This aligns with pattern #1.

3. VALIDATED: Async Messaging as Core Communication

ADR-001 (SNS for everything) is pattern #7 in action. Our entire inter-module and intra-module communication is async via SNS/SQS.

4. VALIDATED: Decomposition by Business Capability

Our modules map to EDRM stages: extract (documentextractor), load (documentloader), upload (documentuploader), export (documentexporter), exchange (documentexchanger). Each is a bounded context aligned with a business capability.

5. VALIDATED: ADR Practice Matches Best Practices

Our ADR format (Status, Context, Decision, Consequences with Positive/Negative/Risks) closely matches Candost's template. We have 10 ADRs (001-010) covering foundational decisions and modernization proposals.

Gaps Identified

1. LOW: No RFC Process for Cross-Team Changes

We use ADRs exclusively. For ADRs 005-010 (modernization roadmap), some decisions impact multiple teams (Rails frontend, Legacy workers, NGE modules). An RFC process would help gather feedback before committing to these decisions.

Recommendation: For ADRs that impact teams beyond the immediate module (e.g., ADR-008 ES upgrade affects Rails search, QLE, and NGE), consider an RFC-first approach. Keep ADRs for module-level decisions.

2. LOW: No Circuit Breaker in Production

We have a circuit-breaker.md pattern document but no production implementation. The article identifies this as a key resilience pattern for synchronous service communication.

Current state: Our architecture is mostly async (SNS/SQS), which naturally provides circuit-breaker-like behavior (messages queue up instead of cascading failures). The one synchronous path — NgePageService HTTP calls — has no circuit breaker (already a backlog item for retry/timeout).

Recommendation: Add circuit breaker to NgePageService when implementing the timeout/retry backlog item. For async paths, the SQS DLQ serves as our circuit breaker equivalent.

The CQRS pattern — separate read and write models — maps naturally to ADR-008 (Elasticsearch upgrade + search service). Elasticsearch is inherently a read-optimized store. A CQRS approach would: - Write path: document processing writes to MySQL (source of truth) - Read path: search queries go to Elasticsearch (denormalized, optimized for search) - Sync: events trigger ES index updates (already how we plan to wire QLE)

This is already implicit in ADR-008's design. Making it explicit would clarify the architecture.

4. INFO: Event Sourcing — PSM as Partial Implementation

PSM captures all events in S3/Athena but doesn't use them to reconstruct state (true event sourcing). If we ever need audit trails or replay capabilities (e.g., for compliance), the event stream is already there — we'd just need to build the reconstruction logic.

New Backlog Items

No new code-level backlog items. The findings are strategic validations and process improvements: - Consider RFC process for cross-team ADRs (005-010) - Circuit breaker for NgePageService (already covered by existing backlog item) - CQRS framing for ADR-008 (informational, no action needed)

Summary

Both articles validate our existing architecture and practices. The 10 microservices patterns article confirms we're using 7 of 10 patterns (database per service, async messaging, strangler, decomposition, aggregator, plus partial saga and event sourcing). The remaining 3 (API gateway via Rails, circuit breaker needed for sync paths, CQRS opportunity for search) are either already in place or identified as future opportunities. The ADR/RFC article validates our ADR format and suggests adding an RFC process for cross-team modernization decisions (ADRs 005-010).

Ask the Architecture ×

Ask questions about Nextpoint architecture, patterns, rules, or any module. Powered by Claude Opus 4.6.