This is the example code for my book Microservice patterns.
-
The code is still work in progress
-
It primarily illustrates the technical aspects of the microservice architecture and so the business logic is minimal
-
The documentation is sparse/non-existent and you will need to look in the book
-
The application consists of many services and so requires a lot of memory. It runs well, for example, on a 16GB Macbook pro.
-
The application’s services and the infrastructure services, such as MySQL and Apache Kafka, are deployed using Docker containers using either Docker Compose or Kubernetes.
Please create a github issue and I’ll do my best to help you.
Not surprisingly, this application has a microservice architecture. There are the following services:
-
ftgo-consumer-service - the
Consumer Service -
ftgo-restaurant-service - the
Restaurant Service -
ftgo-order-service - the
Order Service -
ftgo-kitchen-service - the
Kitchen Service -
ftgo-accounting-service - the
Accounting Service -
ftgo-order-history-service - a
Order History Service, which is a CQRS view -
ftgo-api-gateway - the API gateway
Key points:
-
A service consists of a single Gradle module. For example,
ftgo-order-serviceimplements theOrder Service -
A service is a Spring Boot application
-
A service has a Swagger UI
http://…/swagger-ui.html. Seeopen-swagger-uis.sh -
A service typically consists of the following packages:
-
domain - domain logic including aggregates
-
messaging - messaging adapters
-
web - Spring MVC controllers (HTTP adapters)
-
main - the main application
-
-
The services use the following other frameworks
-
Eventuate Tram framework- implements transactional messaging -
Eventuate Tram Saga framework- implements sagas -
Eventuate Client framework- implements event sourcing
-
This section maps the chapters to the code.
-
The services have a REST API
-
The services also communicate using the Apache Kafka message broker via the
Eventuate Tramframework
The ftgo-order-service uses sagas to maintain data consistency:
The services that participate in these sagas define the following command handlers:
-
Accounting ServiceAccountingServiceCommandHandler -
Consumer ServiceConsumerServiceCommandHandlers -
Kitchen ServiceKitchenServiceCommandHandler -
Order ServiceOrderCommandHandlers
All the services' business logic is implemented using Domain-Driven design aggregates.
-
Accounting Service-
Accountaggregate in the ftgo-accounting-service
-
-
Consumer Service -
Order Service -
Kitchen Service -
Restaurant Service
-
The
Accountaggregate in the ftgo-accounting-service is implemented using event sourcing
-
ftgo-order-history-service is an example of a CQRS view
-
ftgo-api-gateway uses API composition to implement the REST endpoint for retrieving the order history
-
ftgo-api-gateway is the API gateway
-
Java 8+
-
Docker and Docker Compose
-
Internet access so that Gradle and Docker can download dependencies and container images
Temporary: Build the Spring Cloud Contracts using this command:
./gradlew buildContractsBuild the services using this command:
./gradlew assembleTo run the application you must set the DOCKER_HOST_IP environment variable to the IP address of where the Docker containers are running:
-
Docker toolbox/Virtual machine - IP address of the virtual machine
-
Docker for Windows/Mac/Linux - IP address of your laptop/desktop
The value of DOCKER_HOST_IP must be meaningful to both Java services/tests running on your desktop/laptop and to Docker containers. Please do NOT set it to the unresolvable hostname of your machine, localhost or 127.0.0.1 since the Docker containers will probably not work correctly.
You can verify that DOCKER_HOST_IP is set correctly by running this command:
docker run -p 8889:8888 -e DOCKER_DIAGNOSTICS_PORT=8889 -e DOCKER_HOST_IP \ --rm eventuateio/eventuateio-docker-networking-diagnostics:0.2.0.RELEASE
If you want to run Java services/tests within your IDE on your desktop/laptop AND the Docker containers are not accessible via localhost THEN you will need to set DOCKER_HOST_IP within your IDE. How to do this depends on your operating system and IDE. For example, I find it convenient to launch my IDE from the command line and after setting this environment variable.
Run the application using this command:
docker-compose up -dThis can take a while.
Use the services Swagger UIs to invoke the services.
-
Create consumer -
http://${DOCKER_HOST_IP?}:8081/swagger-ui.html -
Create a restaurant -
http://${DOCKER_HOST_IP?}:8084/swagger-ui.html -
Create an order -
http://${DOCKER_HOST_IP?}:8082/swagger-ui.html -
View the order -
http://${DOCKER_HOST_IP?}:8082/swagger-ui.html -
View the order history -
http://${DOCKER_HOST_IP?}:8086/swagger-ui.html
You can also access the application via the API Gateway at http://${DOCKER_HOST_IP?}:8087. However, currently it doesn’t have a Swagger UI so you will have to use curl, for example.
You can find Kubernetes YAML files in the following directories: deployment/kubernetes and */src/deployment/kubernetes. There are also some helpful shell scripts.
You can run this command
./deployment/kubernetes/scripts/kubernetes-deploy-all.sh