Set up an OrderService
microservice with Spring Boot. This service will manage orders, connect to its own MySQL database, and include inter-microservice communication in later labs.
- Ensure the MicroservicesProject workspace is open in VS Code.
- Inside the workspace directory, create a new folder named
OrderService
.
- Open the Command Palette (View > Command Palette or
Ctrl+Shift+P
). - Select Spring Initializr: Generate a Maven Project.
- Configure the options as follows:
- Group Id:
com.microservices
- Artifact Id:
order-service
- Name:
OrderService
- Add dependencies: Spring Web, MySQL Driver, Spring Data JPA.
- Group Id:
- Save the project in the
OrderService
folder.
-
Open the
pom.xml
file in theOrderService
folder and verify that it includes the following dependencies:<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.1.0</version> </dependency> </dependencies>
- In
OrderService/src/main/resources
, openapplication.properties
. - Set up the following properties to configure the application’s port and MySQL database:
server.port=8083 spring.datasource.url=jdbc:mysql://localhost:3308/order_db spring.datasource.username=root spring.datasource.password=Test1234! spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true
- In
com.microservices.orderservice
, create the following folders:model
repository
service
controller
-
In
com.microservices.orderservice.model
, create a class namedOrder.java
. -
Define the
Order
entity with fields and annotations:package com.microservices.order_service.model; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @Entity public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Long productId; private Long userId; private int quantity; private double totalAmount; // Getters and Setters }
- In
com.microservices.orderservice.repository
, create an interfaceOrderRepository.java
:package com.microservices.order_service.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.microservices.order_service.model.Order; public interface OrderRepository extends JpaRepository<Order, Long> { }
- In
com.microservices.orderservice.service
, create a classOrderService.java
:package com.microservices.order_service.service; import com.microservices.order_service.model.Order; import com.microservices.order_service.repository.OrderRepository; import org.springframework.stereotype.Service; import java.util.List; @Service public class OrderService { private final OrderRepository orderRepository; public OrderService(OrderRepository orderRepository) { this.orderRepository = orderRepository; } public List<Order> getAllOrders() { return orderRepository.findAll(); } public Order createOrder(Order order) { return orderRepository.save(order); } }
- In
com.microservices.orderservice.controller
, create a classOrderController.java
:package com.microservices.order_service.controller; import com.microservices.order_service.model.Order; import com.microservices.order_service.service.OrderService; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/orders") public class OrderController { private final OrderService orderService; public OrderController(OrderService orderService) { this.orderService = orderService; } @GetMapping public List<Order> getAllOrders() { return orderService.getAllOrders(); } @PostMapping public Order createOrder(@RequestBody Order order) { return orderService.createOrder(order); } }
- Open Postman and follow these steps:
- Create a new request: Click New > HTTP Request.
- Set the request method: Select GET from the dropdown.
- Enter the URL:
http://localhost:8083/api/orders
. - Send the request: Click Send.
- Verify the response: If there are orders in the database, they will appear in the response. If empty, an empty array
[]
will be returned.
- In the
OrderService
directory, create aDockerfile
:FROM openjdk:17 EXPOSE 8083 ADD target/order-service-0.0.1-SNAPSHOT.jar order-service.jar ENTRYPOINT ["java", "-jar", "order-service.jar"]
- Build the Docker image for OrderService:
docker build -t order-service .
-
In the MicroservicesProject directory, open or create
docker-compose.yml
. -
Add the configurations for
mysql-user
,mysql-product
,mysql-order
,user-service
,product-service
, andorder-service
as follows:version: '3.1' services: # MySQL for UserService mysql-user: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: Test1234! MYSQL_DATABASE: user_db ports: - "3306:3306" # MySQL for ProductService mysql-product: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: Test1234! MYSQL_DATABASE: product_db ports: - "3307:3306" # MySQL for OrderService mysql-order: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: Test1234! MYSQL_DATABASE: order_db ports: - "3308:3306" # UserService user-service: build: ./UserService environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql-user:3306/user_db SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: Test1234! SPRING_JPA_HIBERNATE_DDL_AUTO: update ports: - "8081:8081" depends_on: - mysql-user # ProductService product-service: build: ./ProductService environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql-product:3306/product_db SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: Test1234! SPRING_JPA_HIBERNATE_DDL_AUTO: update ports: - "8082:8082" depends_on: - mysql-product # OrderService order-service: build: ./OrderService environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql-order:3306/order_db SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: Test1234! SPRING_JPA_HIBERNATE_DDL_AUTO: update ports: - "8083:8083" depends_on: - mysql-order
- Start all services with Docker Compose:
docker-compose up -d --build
- Verify that OrderService can connect to its MySQL database.
- Use Postman to test
GET
andPOST
endpoints with Docker running.
- In
com.microservices.orderservice.exception
, create a classOrderNotFoundException.java
:package com.microservices.orderservice.exception; public class OrderNotFoundException extends RuntimeException { public OrderNotFoundException(String message) { super(message); } }
- Add custom exception handling in
OrderController
:@ExceptionHandler(OrderNotFoundException.class) public ResponseEntity<String> handleOrderNotFound(OrderNotFoundException ex) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); }
- Emphasize the importance of keeping each service modular, with its own database and Docker configuration.
- Review what was covered in this lab:
- Created and configured OrderService.
- Dockerized OrderService and connected it to a separate MySQL database.
- Tested endpoints, exception handling, and confirmed modularity.
-
Enhance the Order Entity:
- Add additional fields to the
Order
entity, such asorderDate
andstatus
(e.g.,Pending
,Shipped
,Completed
). - Update the
OrderController
endpoints to include these new fields.
- Add additional fields to the
-
Retrieve Orders by User ID:
- Create a new endpoint in
OrderController
to retrieve all orders associated with a specific user ID (e.g.,GET /api/orders/user/{userId}
). - Write a custom query for this and test it in Postman.
- Create a new endpoint in
-
Environment Variables with Docker:
- Modify the
docker-compose.yml
file to use environment variables for the database configuration instead of hardcoded values. - Test the configuration by running the
OrderService
with Docker Compose.
- Modify the