Skip to content

Latest commit

 

History

History
322 lines (270 loc) · 10.5 KB

File metadata and controls

322 lines (270 loc) · 10.5 KB

Lab 4: Creating the Order Service Microservice

Objective

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.


Steps

1. Open the Project in VS Code

  • Ensure the MicroservicesProject workspace is open in VS Code.

2. Create an OrderService Folder

  • Inside the workspace directory, create a new folder named OrderService.

3. Generate OrderService with Spring Initializr

  • 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.
  • Save the project in the OrderService folder.

4. Verify Dependencies in pom.xml

  • Open the pom.xml file in the OrderService 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>

5. Configure OrderService Application Properties

  • In OrderService/src/main/resources, open application.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

6. Create Project Structure

  • In com.microservices.orderservice, create the following folders:
    • model
    • repository
    • service
    • controller

7. Create the Order Entity

  • In com.microservices.orderservice.model, create a class named Order.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
    }

8. Create the Order Repository

  • In com.microservices.orderservice.repository, create an interface OrderRepository.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> {
    }

9. Implement the Order Service Layer

  • In com.microservices.orderservice.service, create a class OrderService.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);
        }
    }

10. Develop the Order Controller

  • In com.microservices.orderservice.controller, create a class OrderController.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);
        }
    }

11. Test the OrderService GET Endpoint using Postman

  • Open Postman and follow these steps:
    1. Create a new request: Click New > HTTP Request.
    2. Set the request method: Select GET from the dropdown.
    3. Enter the URL: http://localhost:8083/api/orders.
    4. Send the request: Click Send.
    5. Verify the response: If there are orders in the database, they will appear in the response. If empty, an empty array [] will be returned.

12. Containerize OrderService with Docker

  • In the OrderService directory, create a Dockerfile:
    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 .

13. Complete docker-compose.yml for All Services

  • In the MicroservicesProject directory, open or create docker-compose.yml.

  • Add the configurations for mysql-user, mysql-product, mysql-order, user-service, product-service, and order-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

14. Run Docker Compose

  • Start all services with Docker Compose:
    docker-compose up -d --build

15. Test OrderService with Dockerized MySQL

  • Verify that OrderService can connect to its MySQL database.
  • Use Postman to test GET and POST endpoints with Docker running.

16. Implement Exception Handling in OrderService

  • In com.microservices.orderservice.exception, create a class OrderNotFoundException.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());
    }

17. Discuss Best Practices for Modularity and Separation

  • Emphasize the importance of keeping each service modular, with its own database and Docker configuration.

18. Summary of Lab

  • 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.

Extra Exercise (20 minutes):

  1. Enhance the Order Entity:

    • Add additional fields to the Order entity, such as orderDate and status (e.g., Pending, Shipped, Completed).
    • Update the OrderController endpoints to include these new fields.
  2. 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.
  3. 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.