--- id: wiki-2026-0508-software-architecture-pattern title: Software Architecture Pattern category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Architecture Patterns, System Design Patterns] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [architecture, patterns, system-design, microservices, serverless] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: multi framework: kubernetes/serverless/edge --- # Software Architecture Pattern ## 매 한 줄 > **"매 architecture pattern 의 problem-driven choice — layered (CRUD), microservices (org / scale), event-driven (decouple), hexagonal (testability), serverless / edge (ops scale)"**. 매 2026 의 reality 의 hybrid — modular monolith + selective microservices + event backbone (Kafka / NATS) + edge (Cloudflare Workers / Deno Deploy / Vercel). 매 single-pattern dogma X — 매 trade-off 의 explicit. ## 매 핵심 ### 매 Major patterns - **Layered (n-tier)**: presentation / business / data — 매 CRUD default. - **Microservices**: 매 service 의 independent deploy + own DB. - **Event-driven (EDA)**: 매 producer-consumer + queue / log. - **Hexagonal (ports & adapters)**: 매 domain 의 IO 의 isolate. - **CQRS + Event Sourcing**: read / write split, append-only event. - **Modular Monolith**: 매 monolith 위 의 boundary — 매 underrated 2026 default. - **Serverless**: FaaS, 매 ops-zero, cold-start trade. - **Edge / Distributed**: 매 user-near, 매 SQLite-replicated (Turso, D1). ### 매 Cross-cutting - **API Gateway**: 매 frontend의 single entry. - **BFF**: 매 client-specific aggregator. - **Saga**: 매 distributed transaction. - **Outbox**: 매 db + event 의 atomic publish. - **CRDT**: 매 multi-region eventual consistency. ### 매 Modern (2026) trends - **Modular monolith** 의 first — 매 microservices 의 premature 의 X. - **Edge runtime** (Workers, Lambda@Edge) 의 read path. - **AI-augmented architect** — Claude / GPT-5 의 ADR draft / pattern fit review. - **Event streaming default** — Kafka / Redpanda / NATS JetStream. ### 매 응용 1. SaaS multi-tenant — modular monolith + tenant DB. 2. E-commerce — microservices + saga + event backbone. 3. Real-time collab — CRDT + edge + WebSocket. 4. AI app — gateway + queue + worker (LLM inference). ## 💻 패턴 ### Hexagonal (ports & adapters, Python) ```python from typing import Protocol # 매 port (domain interface) class OrderRepo(Protocol): def save(self, order: "Order") -> None: ... def by_id(self, id: str) -> "Order | None": ... # 매 domain (pure) class Order: def __init__(self, id, items): self.id, self.items = id, items def total(self): return sum(i.price for i in self.items) class PlaceOrder: def __init__(self, repo: OrderRepo): self.repo = repo def __call__(self, order: Order): if order.total() <= 0: raise ValueError("empty") self.repo.save(order) # 매 adapter (Postgres impl) — 매 domain 의 zero coupling class PgOrderRepo: def __init__(self, conn): self.conn = conn def save(self, order): self.conn.execute("INSERT ...", ...) def by_id(self, id): ... ``` ### CQRS + Event Sourcing (skeleton) ```python from dataclasses import dataclass @dataclass(frozen=True) class OrderPlaced: order_id: str; total: float class OrderAggregate: def __init__(self): self.id = None; self.total = 0 def apply(self, event): if isinstance(event, OrderPlaced): self.id = event.order_id; self.total = event.total class EventStore: def __init__(self): self.events = [] def append(self, e): self.events.append(e) def load(self, id): agg = OrderAggregate() for e in self.events: if getattr(e, "order_id", None) == id: agg.apply(e) return agg ``` ### Outbox pattern (atomic db + event) ```sql BEGIN; INSERT INTO orders (id, total) VALUES ('o1', 100); INSERT INTO outbox (aggregate_id, type, payload, created_at) VALUES ('o1', 'OrderPlaced', '{"id":"o1","total":100}', NOW()); COMMIT; -- 매 worker 의 outbox 의 poll → Kafka publish → mark sent ``` ### Saga (orchestration, TypeScript) ```typescript async function placeOrderSaga(order: Order) { const compensations: (() => Promise)[] = []; try { await reserveStock(order); compensations.push(() => releaseStock(order)); await chargePayment(order); compensations.push(() => refund(order)); await scheduleShipment(order); } catch (e) { for (const c of compensations.reverse()) await c().catch(() => {}); throw e; } } ``` ### Edge handler (Cloudflare Workers + D1) ```typescript export default { async fetch(req: Request, env: { DB: D1Database }) { const url = new URL(req.url); if (url.pathname === "/api/post" && req.method === "GET") { const id = url.searchParams.get("id")!; const row = await env.DB.prepare("SELECT * FROM posts WHERE id = ?") .bind(id).first(); return Response.json(row, { headers: { "cache-control": "public, max-age=60, s-maxage=300" }, }); } return new Response("not found", { status: 404 }); }, }; ``` ### Modular Monolith (Go module structure) ``` cmd/api/main.go internal/ billing/ # 매 module — own domain, own table prefix api.go domain.go repo.go catalog/ api.go ... shared/ events.go # 매 cross-module event bus ``` ### Event-driven (NATS JetStream) ```typescript import { connect, JSONCodec } from "nats"; const nc = await connect({ servers: "nats://nats:4222" }); const js = nc.jetstream(); const jc = JSONCodec(); // publish await js.publish("orders.placed", jc.encode({ id: "o1", total: 100 })); // subscribe (durable consumer) const c = await js.consumers.get("ORDERS", "ship-worker"); const iter = await c.consume(); for await (const m of iter) { await ship(jc.decode(m.data)); m.ack(); } ``` ### API Gateway (Kong declarative) ```yaml _format_version: "3.0" services: - name: orders url: http://orders.internal:8080 routes: [{ paths: ["/orders"], strip_path: false }] plugins: - name: rate-limiting config: { minute: 60, policy: redis, redis_host: redis } - name: jwt ``` ## 매 결정 기준 | 상황 | Pattern | |---|---| | Small team, CRUD | Layered or Modular Monolith | | Org scaling, 매 indep deploy | Microservices (with care) | | Audit / replay | Event Sourcing + CQRS | | Read-heavy global | Edge + cache | | Distributed transactions | Saga + Outbox | | Real-time collab | CRDT + WebSocket | | Spiky / unpredictable | Serverless | **기본값**: Modular Monolith first. 매 split 의 evidence-driven (org boundary + perf SLO). ## 🔗 Graph - 부모: [[System-Design]] - 변형: [[Microservices]] · [[Event-Driven-Architecture]] · [[Hexagonal Architecture]] · [[CQRS]] - 응용: [[Modular Monolith]] - Adjacent: [[API-Gateway]] · [[Service Mesh]] · [[Edge Computing|Edge-Computing]] ## 🤖 LLM 활용 **언제**: ADR draft, 매 pattern fit review (problem → pattern recommendation), trade-off matrix generate. **언제 X**: actual capacity planning (load test), team-specific tech-stack lock-in (org context). ## ❌ 안티패턴 - **Premature microservices**: 매 distributed monolith — 매 worst. - **Distributed transaction (2PC)**: 매 saga 의 use. - **Shared DB across services**: 매 microservices 의 violate. - **No outbox**: 매 dual-write inconsistency. - **Pattern dogma**: 매 trade-off 의 explicit X. ## 🧪 검증 / 중복 - Verified (Fowler, Vernon, Newman, Richardson architecture references). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — full pattern catalog with code examples |