C4 Container — service topology & protocols

10 services grouped by domain (Identity · Catalog · Transaction) with REST, gRPC, GraphQL Federation, and Kafka edges. Source: 03-c4-container.mermaid

100%
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#FF9900','primaryBorderColor':'#232F3E','primaryTextColor':'#232F3E','lineColor':'#232F3E','secondaryColor':'#EAF2FB','tertiaryColor':'#F7F8FA','fontFamily':'Helvetica, Arial, sans-serif'}}}%%
flowchart TB
    %% ===== C4-Container style diagram =====
    %% Notation: rectangle = Container (deployable unit), cylinder = Data store,
    %% stadium = External system, hexagon = Person. Protocol annotations on edges.

    %% ---------- People / External ----------
    user(["fa:fa-user Customer
browser + mobile"]):::person stripe{{"Stripe
external PSP"}}:::ext email{{"SES / SendGrid
transactional email"}}:::ext %% ---------- Edge ---------- subgraph edge[" Edge Tier "] direction TB alb["ALB + AWS WAF
HTTPS · TLS via ACM"]:::edge kong["kong-gateway
Kong OSS
JWT · rate-limit · CORS · CSRF"]:::svc end %% ---------- Frontend ---------- subgraph fe[" Frontend "] direction TB client[["client
Next.js 16 (App Router) · TS
SSR + Server Actions"]]:::svc end %% ---------- GraphQL Federation ---------- subgraph gql[" GraphQL Federation "] direction TB router[["apollo-router
Apollo Router v2.1
supergraph gateway"]]:::svc end %% ---------- Identity domain ---------- subgraph identity[" Identity "] direction TB auth[["auth-service
NestJS 10 · Node 24
signup · login · JWT"]]:::svc user_svc[["user-service
NestJS 10 · Node 24
profile · prefs · billing"]]:::svc auth_db[(auth_db
RDS PostgreSQL)]:::db user_db[(user_db
RDS PostgreSQL)]:::db auth --- auth_db user_svc --- user_db end %% ---------- Catalog domain ---------- subgraph catalog[" Catalog "] direction TB ticket[["ticket-service
Go 1.23 · Echo v4 · gqlgen
quota · reserve · finalize"]]:::svc venue[["venue-service
Go 1.23 · Echo v4 · gqlgen
seating plan · seat holds · SSE"]]:::svc ticket_db[(ticket_db
MongoDB 7)]:::db venue_db[(venue_db
RDS PostgreSQL)]:::db venue_redis[(ElastiCache Redis
seat hold hot path)]:::db ticket --- ticket_db venue --- venue_db venue --- venue_redis end %% ---------- Transaction domain ---------- subgraph txn[" Transaction "] direction TB order[["order-service
Java 21 · Spring Boot 4
saga orchestrator · outbox"]]:::svc payment[["payment-service
NestJS 10 · Node 24
Stripe intents · webhooks"]]:::svc expiration[["expiration-service
Go 1.23
Redis ZSET timers"]]:::svc order_db[(order_db
RDS PostgreSQL
+ outbox)]:::db payment_db[(payment_db
RDS PostgreSQL)]:::db redis[(ElastiCache Redis
timers · cache · idempotency)]:::db order --- order_db payment --- payment_db expiration --- redis end %% ---------- Messaging ---------- subgraph bus[" Async Messaging "] direction LR kafka{{"Amazon MSK · Kafka
CloudEvents v1.0 envelopes"}}:::mq sr[["Glue Schema Registry
Avro/JSON Schema"]]:::mq kafka --- sr end %% ===== Synchronous edges (HTTP/gRPC) ===== user -- HTTPS --> alb alb --> kong kong -- SSR --> client kong -- "REST /auth/*" --> auth kong -- "REST /users/*" --> user_svc kong -- "REST /tickets/*" --> ticket kong -- "REST /venues/*" --> venue kong -- "REST /orders/*" --> order kong -- "REST /payments/*" --> payment kong -- "Stripe webhook" --> payment kong -- "POST /graphql" --> router %% Apollo Federation subgraph edges router -. "subgraph" .-> auth router -. "subgraph" .-> user_svc router -. "subgraph" .-> ticket router -. "subgraph" .-> venue router -. "subgraph" .-> order router -. "subgraph" .-> payment %% gRPC inside the mesh order == "gRPC ReserveQuota / Finalize / Release" ==> ticket order == "gRPC ReserveHeldSeats / AutoAssign / Finalize" ==> venue ticket == "gRPC GetSeatingPlan" ==> venue auth -. "JWKS (pub key)" .-> kong client -- "server-to-server API" --> kong %% External payment -- "HTTPS PaymentIntents" --> stripe payment -- "email receipt" --> email %% ===== Asynchronous edges (Kafka) ===== order -- "produces
orders.order.{created,cancelled,completed}" --> kafka kafka -- "consumes" --> ticket kafka -- "consumes" --> venue kafka -- "consumes" --> expiration kafka -- "consumes" --> payment expiration -- "produces
expiration.order.expiration_complete" --> kafka kafka -- "consumes" --> order ticket -- "produces
tickets.ticket.{created,updated}" --> kafka %% ===== Styles ===== classDef svc fill:#FF9900,stroke:#232F3E,stroke-width:1.5px,color:#232F3E; classDef db fill:#1A73E8,stroke:#232F3E,stroke-width:1.5px,color:#FFFFFF; classDef mq fill:#7D3C98,stroke:#232F3E,stroke-width:1.5px,color:#FFFFFF; classDef edge fill:#232F3E,stroke:#232F3E,stroke-width:1.5px,color:#FFFFFF; classDef ext fill:#7AA116,stroke:#232F3E,stroke-width:1.5px,color:#FFFFFF; classDef person fill:#FDF6E3,stroke:#232F3E,stroke-width:1.5px,color:#232F3E;