The FTGO application is a food delivery system built entirely on a microservice architecture. This page covers how the system is decomposed into independent services, how those services communicate with each other, which infrastructure components underpin the platform, and how each service is structured internally.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/microservices-patterns/ftgo-application/llms.txt
Use this file to discover all available pages before exploring further.
Microservice decomposition
The application is split into nine independently deployable services, each owning its own domain logic and data store.Consumer Service
Manages consumer accounts and validates consumers during order placement. Exposed on port 8081.
Restaurant Service
Maintains restaurant and menu data used when creating orders. Exposed on port 8084.
Order Service
Core service that creates, revises, and cancels orders. Coordinates multi-service sagas to maintain data consistency. Exposed on port 8082.
Kitchen Service
Receives kitchen tickets when orders are placed and tracks ticket status. Exposed on port 8083.
Accounting Service
Manages consumer billing using event sourcing for the
Account aggregate. Exposed on port 8085.Delivery Service
Tracks delivery status for placed orders. Exposed on port 8089.
Order History Service
A CQRS read-model view that projects order history from domain events into DynamoDB. Exposed on port 8086.
API Gateway
Single entry point for external clients. Uses API composition to aggregate data from multiple services. Exposed on port 8087.
GraphQL API Gateway
An alternative API gateway that exposes a GraphQL schema over the same downstream services.
All business logic is implemented using Domain-Driven Design aggregates. Each service owns its aggregate and is the sole writer of its data.
Communication patterns
Services communicate in two ways: synchronous REST calls for request/response interactions, and asynchronous messaging over Apache Kafka for event-driven and saga-based coordination.REST APIs
Every service exposes a Spring MVC REST API. The API Gateway routes inbound HTTP requests to the appropriate downstream service. For queries that require data from more than one service, the gateway uses API composition: it fans out parallel reactive requests and merges the results before responding to the caller. For example,GET /orders/{orderId} on the gateway concurrently fetches data from Order Service, Kitchen Service, Delivery Service, and Accounting Service, then combines them into a single OrderDetails response using Project Reactor’s Mono.zip.
Asynchronous messaging via Kafka
Services publish domain events and send commands to each other through Apache Kafka, brokered by the Eventuate Tram framework. Eventuate Tram guarantees transactional messaging: outbound messages are written to the database in the same transaction as the business operation, then forwarded to Kafka by the CDC service via MySQL binlog replication. The Eventuate Tram Sagas framework orchestrates multi-step, multi-service workflows as sagas. The Order Service defines three sagas:CreateOrderSaga— coordinates consumer validation, restaurant approval, kitchen ticket creation, and payment authorization when placing a new order.CancelOrderSaga— coordinates the reversal of a kitchen ticket and payment when an order is cancelled.ReviseOrderSaga— coordinates line-item quantity changes across services when an order is revised.
The Accounting Service’s
Account aggregate is implemented using event sourcing via the Eventuate Client framework, storing state as a sequence of domain events rather than current-value rows.Infrastructure services
MySQL
MySQL
Each business service has its own MySQL schema (e.g.,
ftgo_order_service, ftgo_kitchen_service). Schemas are isolated to enforce service autonomy — no service reads another service’s database directly. MySQL also stores the Eventuate Tram outbox tables used for transactional messaging.Apache Kafka
Apache Kafka
The central message broker. Kafka receives events forwarded from MySQL by the CDC service and delivers them to subscribing services. Configured on port 9092, with an internal listener on port 29092 for container-to-container traffic.
Zookeeper
Zookeeper
Required by Kafka for cluster coordination. Runs on port 2181 and is a dependency for services that connect to Kafka directly.
CDC Service
CDC Service
The Eventuate CDC (Change Data Capture) service reads the MySQL binlog and publishes outbox messages to Kafka topics. It is configured with one pipeline per service schema, ensuring transactional outbox delivery for all services.
DynamoDB (local)
DynamoDB (local)
Used exclusively by the Order History Service as the backing store for its CQRS view. A local DynamoDB container is used for development and Docker Compose deployments. The
dynamodblocal-init container initialises the required tables on startup.Zipkin
Zipkin
Distributed tracing is enabled on Order Service, Delivery Service, and API Gateway via Spring Cloud Sleuth with 100% sampling probability. Traces are reported to the Zipkin server on port 9411.
Service internal structure
Each service is a single Gradle module and a standalone Spring Boot application. The source code is organised into four packages:| Package | Responsibility |
|---|---|
domain | Domain aggregates, value objects, and business logic. For example, the Order aggregate in Order Service manages order state transitions (APPROVAL_PENDING → APPROVED → CANCEL_PENDING → CANCELLED) and publishes domain events such as OrderCreatedEvent, OrderAuthorized, and OrderCancelled. |
messaging | Messaging adapters that subscribe to Kafka topics and implement command handlers for saga participation. |
web | Spring MVC REST controllers that expose the service’s HTTP API. Each service includes a Swagger UI at /swagger-ui/index.html. |
main | Spring Boot application entry point and configuration. |