Skip to main content

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.

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.

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.
Each participating service (Accounting, Consumer, Kitchen, Order) implements a command handler that processes saga commands and publishes reply messages.
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

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.
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.
Required by Kafka for cluster coordination. Runs on port 2181 and is a dependency for services that connect to Kafka directly.
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.
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.
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:
PackageResponsibility
domainDomain aggregates, value objects, and business logic. For example, the Order aggregate in Order Service manages order state transitions (APPROVAL_PENDINGAPPROVEDCANCEL_PENDINGCANCELLED) and publishes domain events such as OrderCreatedEvent, OrderAuthorized, and OrderCancelled.
messagingMessaging adapters that subscribe to Kafka topics and implement command handlers for saga participation.
webSpring MVC REST controllers that expose the service’s HTTP API. Each service includes a Swagger UI at /swagger-ui/index.html.
mainSpring Boot application entry point and configuration.
During local development you can explore each service’s API through its Swagger UI. For example, Consumer Service is at http://localhost:8081/swagger-ui/index.html and Order Service is at http://localhost:8082/swagger-ui/index.html.

Build docs developers (and LLMs) love