Spring Boot Microservices Config Server Example

In this tutorial, we'll create two Spring Boot microservices and a Config Server to manage their configurations. We'll use the latest Spring Boot version 3.2+ and Spring Cloud 2023.x. This guide is intended for beginners and includes detailed explanations for each step.

Introduction to Config Server

A Config Server is a central place to manage external properties for applications across all environments. It allows microservices to read their configuration from a centralized server, making it easier to manage configuration changes without having to redeploy the applications. This helps in maintaining consistency across multiple microservices and environments.

Flow of the System

  1. Config Server: Acts as a central repository for configuration files.
  2. Microservices: Fetch their configuration from the Config Server.
  3. Configuration Management: Centralized management of configuration properties for multiple environments.

Prerequisites

  • JDK 17 or later
  • Maven or Gradle
  • IDE (IntelliJ IDEA, Eclipse, etc.)

Step 1: Set Up the Config Server

1.1 Create the Project

Use Spring Initializr to create a new project with the following dependencies:

  • Config Server

1.2 Configure application.properties

Set up the application properties for the Config Server.

server.port=8888
spring.application.name=config-server

spring.cloud.config.server.git.uri=https://github.com/your-repo/config-repo
spring.cloud.config.server.git.clone-on-start=true

Explanation:

  • server.port=8888: Sets the port for the Config Server.
  • spring.application.name=config-server: Names the application.
  • spring.cloud.config.server.git.uri: Specifies the URI of the Git repository where configuration files are stored.
  • spring.cloud.config.server.git.clone-on-start=true: Clones the Git repository on startup.

1.3 Enable Config Server

Add the @EnableConfigServer annotation to the main application class.

package com.example.configserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

Explanation:

  • @EnableConfigServer: Enables the Config Server functionality in your Spring Boot application.

Step 2: Create Configuration Repository

Create a Git repository (e.g., config-repo) and add configuration files for product-service and order-service. The structure should be as follows:

config-repo
|-- product-service.yml
|-- order-service.yml

Example product-service.yml:

server:
  port: 8081

product:
  default-name: "Default Product Name"
  default-price: 99.99

Example order-service.yml:

server:
  port: 8082

order:
  default-status: "PENDING"

Step 3: Set Up product-service

3.1 Create the Project

Use Spring Initializr to create a new project with the following dependencies:

  • Spring Web
  • Config Client

3.2 Configure application.properties

Set up the application.properties for product-service to fetch configuration from the Config Server.

spring.application.name=product-service
spring.cloud.config.uri=http://localhost:8888

Explanation:

  • spring.application.name=product-service: Names the application.
  • spring.cloud.config.uri=http://localhost:8888: Specifies the URI of the Config Server.

3.3 Enable Config Client

No specific annotation is required to enable the config client as it is automatically enabled when you include the Config Client dependency.

3.4 Create a Product Model

Create a simple Product model to represent the product data.

package com.example.productservice;

public class Product {
    private String id;
    private String name;
    private double price;

    // Constructor, getters, and setters
    public Product(String id, String name, double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

Explanation:

  • This class represents the product data with attributes id, name, and price.

3.5 Create a Controller

Create a controller to handle product-related requests.

package com.example.productservice;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProductController {

    @Value("${product.default-name}")
    private String defaultName;

    @Value("${product.default-price}")
    private double defaultPrice;

    @GetMapping("/products/{id}")
    public Product getProduct(@PathVariable String id) {
        return new Product(id, defaultName, defaultPrice);
    }
}

Explanation:

  • @Value("${product.default-name}"): Injects the default product name from the configuration.
  • @Value("${product.default-price}"): Injects the default product price from the configuration.

Step 4: Set Up order-service

4.1 Create the Project

Use Spring Initializr to create a new project with the following dependencies:

  • Spring Web
  • Config Client

4.2 Configure application.properties

Set up the application.properties for order-service to fetch configuration from the Config Server.

spring.application.name=order-service
spring.cloud.config.uri=http://localhost:8888

Explanation:

  • spring.application.name=order-service: Names the application.
  • spring.cloud.config.uri=http://localhost:8888: Specifies the URI of the Config Server.

4.3 Enable Config Client

No specific annotation is required to enable the config client as it is automatically enabled when you include the Config Client dependency.

4.4 Create an Order Model

Create a simple Order model to represent the order data.

package com.example.orderservice;

public class Order {
    private String id;
    private String status;

    // Constructor, getters, and setters
    public Order(String id, String status) {
        this.id = id;
        this.status = status;
    }

    public String getId() {
        return id;
    }

    public String getStatus() {
        return status;
    }
}

Explanation:

  • This class represents the order data with attributes id and status.

4.5 Create a Controller

Create a controller to handle order-related requests.

package com.example.orderservice;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class OrderController {

    @Value("${order.default-status}")
    private String defaultStatus;

    @GetMapping("/orders/{id}")
    public Order getOrder(@PathVariable String id) {
        return new Order(id, defaultStatus);
    }
}

Explanation:

  • @Value("${order.default-status}"): Injects the default order status from the configuration.

Step 5: Run the Microservices

  1. Start the Config Server: Run the ConfigServerApplication class.
  2. Start product-service: Run the ProductServiceApplication class.
  3. Start order-service: Run the OrderServiceApplication class.

Step 6: Test the Configuration

Open your browser or use a tool like Postman to test the endpoints:

  • product-service: http://localhost:8081/products/1
  • order-service: http://localhost:8082/orders/1

The response from product-service should include the default product name and price fetched from the Config Server. The response from order-service should include the default order status fetched from the Config Server.

Conclusion

You have successfully set up two Spring Boot microservices and a Config Server to manage their configurations. The Config Server provides a centralized way to manage configuration properties for multiple environments, simplifying configuration management and improving consistency across microservices. This setup can be expanded to include more microservices and more complex configuration management scenarios.


Comments