This project showcases the implementation of a Microservices Architecture with a focus on Apache Kafka for inter-service communication. The architecture consists of three independent microservices:
- Order-Service: Produces Kafka messages with order details when an API endpoint is triggered.
- Inventory-Service: Consumes Kafka messages and updates inventory based on orders.
- Billing-Service: Consumes Kafka messages and creates billing records for each order.
Each microservice is designed to handle its responsibilities independently, ensuring scalability, modularity, and maintainability.
- Spring Boot
- Spring Web
- Spring Data JPA
- Spring Kafka
- Kafka for message brokering
- MySQL as the database
- Responsibilities:
- Acts as a Kafka producer.
- Exposes an endpoint to place orders.
http://localhost:8080/orders/place-order
- Publishes order details as messages to the Kafka topic
order-topic
.
- Dependencies:
spring-boot-starter-web
spring-boot-starter-data-jpa
spring-kafka
- Responsibilities:
- Acts as a Kafka consumer.
- Updates the inventory table based on orders placed.
- Dependencies:
spring-boot-starter-data-jpa
spring-kafka
- Responsibilities:
- Acts as a Kafka consumer.
- Saves billing records for each order in the billing table.
- Dependencies:
spring-boot-starter-data-jpa
spring-kafka
-
Install Kafka and ensure it is running.
-
Install Java 17 or higher.
-
Install Maven for dependency management.
-
Install MySQL and configure the database for each service.
- Using DBeaver for working with database
CREATE DATABASE products_database;
Navigate to src/main/resources/application.properties
and make the below changes for each service.
spring.datasource.username = <your-username>
spring.datasource.password = <your-password>
spring.jpa.generate-ddl = true
spring.jpa.hibernate.ddl-auto = update
Replace <your-username>
and <your-password>
with your db credentials
-
Order-Service:
- Navigate to the
order-service
directory. - Run:
mvn clean install
Once the application is up and running, verify the table `orders' is created. Refresh the database.mvn spring-boot:run
- Navigate to the
-
API Endpoint:
http://localhost:8080/orders/place-order
- Open Postman, and test the endpoint by providing the below request body.
{ "productName": "iPhone 14", "quantity": 1, "price": 999.99 }
Verify the logs
Verify the table orders
is updated.
USE products_database;
SELECT * FROM orders o ;
Verify the kafka-topic. After POST request is made, the service produce the message in topic order-topic
./bin/kafka-topics.sh --bootstrap-server localhost:9092 --list
- Inventory-Service:
Inventory Service is a
consumer
service that works with tableinventory
which update the table when message is consumed from topicorder-topic
produced byorder-service
Before running this service, create a table inventory and insert some data to work with. Use the following queries.
CREATE TABLE inventory (
id INT PRIMARY KEY,
product_name VARCHAR(255) NOT NULL,
available_quantity INT NOT NULL,
price DECIMAL(10, 2) NOT NULL
);
INSERT INTO inventory (id, product_name, available_quantity, price)
VALUES
(1, 'iPhone 14', 50, 999.99),
(2, 'Samsung Galaxy S23', 50, 999.99),
(3, 'Google Pixel 7', 50, 999.99);
- Navigate to the
inventory-service
directory.-
Run:
mvn clean install
mvn spring-boot:run
-
Verify in kafka. The consumer group
inventory-group-id
is created.
./bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list
-
After inventory-service
is up and running, run the billing-service
- Inventory gets updated automatically when an order is placed.
-
Billing-Service:
-
Navigate to the
billing-service
directory. -
Run:
mvn clean install
mvn spring-boot:run
-
Verify the logs. The consumer is created.
-
Verify in kafka. The consumer group
billing-group-id
is created.
-
./bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list
Billing table table is automatically created when application is up and running.
SELECT * FROM billing b ;
![ss18.png](screenshots/local/ss18.png) - `order-service: Produce the message and update the orders table` ![ss9.png](screenshots/local/ss9.png) ![ss11.png](screenshots/local/ss11.png)
inventory-service: Consume the message and update the inventory table
billing-service: Consume the message and update the billing table
./bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic order-topic --from-beginning
Each service uses MySQL as the database. Ensure the database and tables are created before running the services.
-
Order-Service:
- Table:
orders
- Schema: Automatically created when the application runs.
- Table:
-
Inventory-Service:
- Table:
inventory
- Schema: Use the provided schema.sql file located in src/main/resources to create and populate the table.
- Table:
-
Billing-Service:
- Table:
billing
- Schema: Automatically created when the application runs.
- Table:
All Kafka properties are configured in the Java configuration class for each service. There is no need for Kafka-related settings in the application.properties
file.
- Topic:
order-topic
- Producer: Order-Service
- Consumers: Inventory-Service, Billing-Service
- Implement API Gateway for routing and authentication.
- Add Swagger documentation for REST APIs.
- Implement distributed tracing using Zipkin or Jaeger.
- Add resilience patterns with Circuit Breakers using Resilience4j.
- Java:
java 17.0.1 2021-10-19 LTS Java(TM) SE Runtime Environment (build 17.0.1+12-LTS-39) Java HotSpot(TM) 64-Bit Server VM (build 17.0.1+12-LTS-39, mixed mode, sharing)
- Maven:
Apache Maven 3.9.9
- Kafka:
3.9.0
- Database: MySQL
- OS: macOS (Apple Silicon)