While a microservices architecture defines this system for the efficient governance of stock, orders, and products—with an emphasis on flexibility and scalability—each microservice attends to a respective function, ranging from product management to stock tracking and order processing; thus, it can be developed and deployed independently.
Built-in Spring Boot and Spring Cloud, this system allows for inter-service communication, introduces fault tolerance, and realizes ease of maintenance. It is API-driven with RESTful APIs, deployed in Docker with a MySQL database and an API Gateway, to get real-time inventory snippets and perform business transactions seamlessly. The microservices approach itself stands for a scalable, resilient, and adaptive solution to use for modern inventory management.
Microservice Architecture
Building a Scalable E-Commerce Inventory Management System with Microservices using Spring Boot#
Extract that zip files inside a folder (ecommerce).
Extract that zip files inside a folder (ecommerce)
Open that folder (ecommerce) inside your ide (IntelliJ, VS Code, etc.). Don’t open the applications separately. Reload maven.
Ide image
If you missed this symbol then you can add maven projects like this.
Ide Image
2. Make Changes Inside pom.xml For SpringBoot New Version:#
Whenever we will use SpringBoot between <version>3.3.6</version> and <version>3.4.2</version> to enable Lombok we need to make some changes inside our pom.xml. Inside the plugins part of the XML file, we can see two plugins are there <artifactId>maven-compiler-plugin</artifactId> and <artifactId>spring-boot-maven-plugin</artifactId>. Inside the first plugin (<artifactId>maven-compiler-plugin</artifactId> ), we need to add the Lombok version.
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.36</version> --- add this only and reload your maven </path> </annotationProcessorPaths> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build>
Common Configuration: (inside application.properties/application.yml file) server.servlet.context-path=<any path> use any path
server.port=<any port> use any unused port
Database Configuration:
spring.datasource.url=jdbc:postgresql://localhost:5432/<Database Name> use db name that you create inside your db.
spring.datasource.username=<username> add your user name.
spring.datasource.password=<password> add your password.
spring.jpa.hibernate.ddl-auto=create-drop use any of (create-drop/update/create)
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
The server.servlet.context-path in Spring Boot sets a base URL for all endpoints, helping to avoid conflicts, organize APIs, and manage multiple services efficiently. It is useful in microservices architectures, simplifies reverse proxy/load balancer configurations, and enables environment-specific deployments. Configuring it in application.properties or application.yml ensures structured and scalable API management.
Inventory Service Database Configuration:
Inventory Service Database Configuration
Order Service Database Configuration:
Order Service Database Configuration
servlet.context-path=/api/v1 sets a base path for all endpoints, so URLs will be prefixed with /api/v1. For example, /users becomes http://localhost:8080/api/v1/users. This helps with API versioning and organization.
Connect the database.
If you are using dBeaver
DBeaver image
If you are using direct pgAdmin4. (After login with password).
package com.codingshuttle.ecommerce.inventory_service.controllers;import com.codingshuttle.ecommerce.inventory_service.dtos.ProductDto;import com.codingshuttle.ecommerce.inventory_service.services.ProductService;import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.*;import java.util.List;@RestController@Slf4j@RequiredArgsConstructor@RequestMapping("/products") //you have to add "/api/v1" before adding this endpointpublic class ProductsController { private final ProductService productService; @GetMapping public ResponseEntity<List<ProductDto>> getAllProducts(){ log.info("Fetching all products via controller"); List<ProductDto> inventories = productService.getAllProducts(); return ResponseEntity.ok(inventories); } @GetMapping("/{id}") public ResponseEntity<ProductDto> getProductById(@PathVariable Long id){ log.info("Fetching product by id via controller"); ProductDto inventory = productService.getProductById(id); return ResponseEntity.ok(inventory); }}
Service Class:
package com.codingshuttle.ecommerce.inventory_service.services;import com.codingshuttle.ecommerce.inventory_service.dtos.ProductDto;import com.codingshuttle.ecommerce.inventory_service.entities.ProductEntity;import com.codingshuttle.ecommerce.inventory_service.repositories.ProductRepo;import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.modelmapper.ModelMapper;import org.springframework.stereotype.Service;import java.util.List;import java.util.Optional;@Service@Slf4j@RequiredArgsConstructorpublic class ProductService { private final ProductRepo productRepo; private final ModelMapper modelMapper; public List<ProductDto> getAllProducts() { log.info("Fetching all inventory items"); List<ProductEntity> inventories = productRepo.findAll(); return inventories.stream() .map(productEntity -> modelMapper.map(productEntity,ProductDto.class)) //.collect(Collectors.toList()); .toList(); } public ProductDto getProductById(Long id) { log.info("Fetching Product with Id: {}",id); Optional<ProductEntity> inventory = productRepo.findById(id); return inventory.map(item -> modelMapper.map(item,ProductDto.class)) .orElseThrow(()->new RuntimeException("Inventory not found")); }}
Developing the Order Service
DTO/DAO Class:
package com.codingshuttle.ecommerce.order_service.dtos;import com.codingshuttle.ecommerce.order_service.entities.OrderItemsEntity;import lombok.Data;import java.util.List;@Datapublic class OrderRequestDto { private Long id; private List<OrderItemsEntity> items; private Double totalPrice;}package com.codingshuttle.ecommerce.order_service.dtos;import lombok.Data;@Datapublic class OrderRequestItemDto { private Long id; private Long productId; private Integer quantity;}
package com.codingshuttle.ecommerce.order_service.controllers;import com.codingshuttle.ecommerce.order_service.dtos.OrderRequestDto;import com.codingshuttle.ecommerce.order_service.services.OrderService;import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.*;import java.util.List;@RestController@RequiredArgsConstructor@RequestMapping("/orders")@Slf4jpublic class OrderController { private final OrderService orderService; @GetMapping public ResponseEntity<List<OrderRequestDto>> getAllOrders(){ log.info("Fetching all orders via controller"); List<OrderRequestDto> orders = orderService.getAllOrders(); return ResponseEntity.ok(orders); } @GetMapping("/{id}") public ResponseEntity<OrderRequestDto> getOrderById(@PathVariable Long id){ log.info("Fetching order by id via controller"); OrderRequestDto order = orderService.getOrderById(id); return ResponseEntity.ok(order); }}
Service Class:
package com.codingshuttle.ecommerce.order_service.services;import com.codingshuttle.ecommerce.order_service.dtos.OrderRequestDto;import com.codingshuttle.ecommerce.order_service.entities.OrdersEntity;import com.codingshuttle.ecommerce.order_service.repositories.OrderRepo;import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.modelmapper.ModelMapper;import org.springframework.stereotype.Service;import java.util.List;@Service@Slf4j@RequiredArgsConstructorpublic class OrderService { private final OrderRepo orderRepo; private final ModelMapper modelMapper; public List<OrderRequestDto> getAllOrders(){ log.info("Fetching all orders"); List<OrdersEntity> orders = orderRepo.findAll(); return orders.stream() .map(order -> modelMapper.map(order, OrderRequestDto.class)) .toList(); } public OrderRequestDto getOrderById(Long id){ log.info("Fetching order by id"); OrdersEntity order = orderRepo.findById(id).orElseThrow(()->new RuntimeException("Order not found")); return modelMapper.map(order, OrderRequestDto.class); }}
This article discusses the huge potential the microservices-based approach has toward scalability, real-time monitoring, and efficient operation in an Inventory Management System. Based on Spring Boot and REST APIs in conjunction with Docker and MySQL, the technological aspect of this solution ensures automation, fault tolerance, and cloud-native deployment for that flexible, reliable inventory management, prepared for future devices.