saga-full — services reference
Every Kafka-driven service in this repo follows the same outbox-then-poll shape (see Saga Flow for the pattern itself). The table below is what actually differs per service — port, topics, schema, and the one detail worth knowing about each.
Only order-service and api-gateway-service expose an HTTP controller —
payment-service and restaurant-service are Kafka-driven only (their
web/actuator starters exist purely for health probes), and
user-service is gRPC-only with no outbox at all.
| Service | Port / protocol | Publishes | Consumes | Schema | Worth knowing |
|---|---|---|---|---|---|
| user-contract | n/a — contract only | — | — | — | ValidateToken RPC has zero real callers in this repo — see the callout below. |
| user-service | 9090 gRPC only |
— | — | user_service_schema |
No outbox, no HTTP surface. Login's three failure modes all collapse to one generic UNAUTHENTICATED (login-enumeration fix). |
| order-service | 8081 HTTP |
order-created-topic |
restaurant-approved-topic, restaurant-rejected-topic |
order_service_schema |
The saga's entry point and sole owner of order lifecycle state. Ships the outbox row's raw JSON as-is — no deserialize/reserialize round trip. |
| payment-service | 8082 health only |
payment-processed-topic |
order-created-topic, restaurant-rejected-topic |
payment_service_schema |
Two consumer groups on two different topics — one charges, the other (payment-compensation-group) is the saga's real compensating transaction. |
| restaurant-service | 8083 health only |
restaurant-approved-topic or restaurant-rejected-topic |
payment-processed-topic |
restaurant_service_schema |
The one service whose outbox publisher routes to one of two topics by eventType, not a fixed single topic. InventoryItem uses a natural-key String itemCode, not a UUID. |
| api-gateway-service | 8080 HTTP (WebFlux) |
— (proxies only) | — (gRPC client + HTTP routing, no Kafka) | — | Verifies JWTs locally against the same HMAC secret user-service signs with, not via ValidateToken. Circuit breaker falls back to /fallback/orders. |
user.proto's ValidateToken RPC is fully implemented and tested but has
no real caller anywhere in this repo — the original plan was for
api-gateway-service to call it on every guarded request; what got built instead
verifies locally (see the gateway row above). Not a bug — local verification is itself a
legitimate pattern — but it's tested API surface built against a stated intent that was never
wired up. Flagged during the code-review audit, not fixed.