List of microservices design patterns

Here’s a comprehensive list of microservices design patterns, organized by category. These are well-known, industry-recognized patterns used to design, build, deploy, and manage microservices architectures effectively.


🧩 1. Decomposition Patterns

How to break a system into microservices.

  1. Decompose by Business Capability
    • Split services according to business functions (e.g., Order Service, Payment Service).
  2. Decompose by Subdomain (DDD)
    • Use Domain-Driven Design (DDD) to align services with bounded contexts.
  3. Decompose by Transaction or Workflow
    • Break services based on business transactions or workflows.
  4. Strangler Fig Pattern
    • Incrementally replace a monolith by routing requests to new microservices.
  5. Self-Contained Service
    • Each service owns its UI, logic, and data.
  6. Bulkhead Pattern
    • Isolate components so failure in one doesn’t cascade.

βš™οΈ 2. Integration Patterns

How services communicate and integrate.

  1. API Gateway Pattern
    • A single entry point for all clients, routing to backend services.
  2. Aggregator Pattern
    • Combines results from multiple services into one response.
  3. Proxy Pattern
    • Acts as a mediator between client and multiple microservices.
  4. Chained Microservice Pattern
    • Service A calls Service B, which calls Service C, etc.
  5. Message Broker / Event Bus Pattern
    • Asynchronous communication using message queues (e.g., Kafka, RabbitMQ).
  6. Backend for Frontend (BFF)
    • Different gateways for different clients (web, mobile, etc.).
  7. API Composition
    • API layer composes data from multiple microservices.

πŸ’Ύ 3. Database and Data Management Patterns

How each microservice handles data.

  1. Database per Service
    • Each service has its own database to ensure loose coupling.
  2. Shared Database(anti-pattern if overused)
    • Multiple services access one database.
  3. CQRS (Command Query Responsibility Segregation)
    • Separate models for reading and writing data.
  4. Event Sourcing
    • Store changes as a series of events, not just current state.
  5. Saga Pattern
    • Manage distributed transactions using local transactions and events.
  6. Outbox Pattern
    • Ensures reliable event publishing along with database changes.

🧠 4. Observability Patterns

How to monitor and debug microservices.

  1. Log Aggregation
    • Collect logs from all services into a centralized system (e.g., ELK Stack).
  2. Distributed Tracing
    • Trace requests across multiple microservices (e.g., OpenTelemetry, Jaeger).
  3. Metrics and Health Checks
    • Monitor performance, uptime, and service health.
  4. Correlation ID Pattern
    • Use a unique ID to trace a request across services.

πŸ”„ 5. Resilience and Reliability Patterns

How services handle failure gracefully.

  1. Circuit Breaker
    • Prevents a service from making repeated failed calls.
  2. Retry Pattern
    • Automatically retry failed requests.
  3. Timeout Pattern
    • Define request timeout to avoid hanging.
  4. Bulkhead Pattern
    • Isolate services/resources to prevent cascading failures.
  5. Failover Pattern
    • Switch to a backup instance in case of failure.
  6. Compensation Transaction
    • Undo steps when a distributed transaction fails.

πŸš€ 6. Deployment Patterns

How to deploy and version microservices.

  1. Service Instance per Host
    • One instance per VM or container.
  2. Multiple Service Instances per Host
    • Several services share a host.
  3. Service per Container
    • One service per container (common with Docker/Kubernetes).
  4. Blue-Green Deployment
    • Two environments: one live, one idle for seamless updates.
  5. Canary Deployment
    • Release updates gradually to a small subset of users.
  6. Rolling Update
    • Incrementally update instances.
  7. Sidecar Pattern
    • Deploy helper containers (e.g., for logging, monitoring) alongside main service.

πŸ” 7. Security Patterns

How to secure microservices.

  1. Access Token Pattern (JWT / OAuth2)
    • Use tokens for user identity and access control.
  2. API Gateway Authentication
    • Offload auth logic to gateway.
  3. Service-to-Service Authentication (mTLS)
    • Use mutual TLS for secure inter-service communication.
  4. Centralized Security Policy
    • Define and enforce common security rules.
  5. Secrets Management Pattern
    • Securely manage API keys, passwords, etc.

πŸ—οΈ 8. Cross-Cutting Concerns

General-purpose patterns across services.

  1. Service Discovery Pattern
    • Automatically locate service instances (e.g., via Eureka, Consul).
  2. Configuration Server Pattern
    • Centralize configuration (e.g., Spring Cloud Config).
  3. Externalized Configuration
    • Store configuration outside the codebase.
  4. Distributed Cache
    • Use caching layer shared across services.
  5. Anti-Corruption Layer (ACL)
    • Shield microservices from legacy systems.

org.hibernate.LazyInitializationException: could not initialize proxy [com.trb.springboottutorial.entity.Course#1] – no Session

rg.hibernate.LazyInitializationException: could not initialize proxy [com.trb.springboottutorial.entity.Course#1] – no Session

Scenario:Β I have defined Course entity and CourseMaterial entity. Both has one-to-one mapping. A course doesn’t exist with a course material and vice-versa. When I fetch CourseMaterial, I don’t want the Course entity to get fetched as well immediately.

BEFORE CODE FIX

Entity “Course”

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Course {

    @Id
    @SequenceGenerator(name = "courseSequence",
            allocationSize = 1, sequenceName = "course_sequence")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
            generator = "courseSequence")
    private Long courseId;


    private String courseTitle;
    private Integer credit;
}
Entity "CourseMaterial"

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CourseMaterial {

    @Id
    @SequenceGenerator(name = "materialSequence",sequenceName = "material_sequence",
                        allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "materialSequence")
    private Long courseMaterialId;
    private String url;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(
            name = "course_id",
            referencedColumnName = "courseId"
    )
    private Course course;
}

My Test Class

package com.trb.springboottutorial.repository;

import com.trb.springboottutorial.entity.Course;
import com.trb.springboottutorial.entity.CourseMaterial;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class CourseMaterialRepositoryTest {

    @Autowired
    private CourseMaterialRepository courseMaterialRepository;


    @Test
    public void printAllCourseMaterials() {
        List<CourseMaterial> courseMaterialList = courseMaterialRepository.findAll();
        System.out.println(courseMaterialList);

        //could not initialize proxy [com.trb.springboottutorial.entity.Course#1] - no Session
    }

}

Problem is: There is toString() method calling the Course entity when fetching the Course Materials List

Solution: Exclude the Course entity to get fetched in CourseMaterial Entity immediately

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString(exclude = "course")
public class CourseMaterial {

    @Id
    @SequenceGenerator(name = "materialSequence",sequenceName = "material_sequence",
                        allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "materialSequence")
    private Long courseMaterialId;
    private String url;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(
            name = "course_id",
            referencedColumnName = "courseId"
    )
    private Course course;
}

Output

[CourseMaterial(courseMaterialId=2, url=www.technicalrecyclebin.com), CourseMaterial(courseMaterialId=3, url=www.dailycodebuffer.com)]

Happy Learning πŸ™‚

object references an unsaved transient instance – save the transient instance before flushing

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance – save the transient instance before flushing : com.trb.springboottutorial.entity.CourseMaterial.course -> com.trb.springboottutorial.entity.Course; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance – save the transient instance before flushing : com.trb.springboottutorial.entity.CourseMaterial.course -> com.trb.springboottutorial.entity.Course

Scenario: I have defined Course entity and CourseMaterial entity. Both has one-to-one mapping. A course doesn’t exist with a course material and vice-versa. When I try to insert a new CourseMaterial entry into the database, the Course insertion entry also should happen.





BEFORE CODE FIX

package com.trb.springboottutorial.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CourseMaterial {

    @Id
    @SequenceGenerator(name = "materialSequence",sequenceName = "material_sequence",
                        allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "materialSequence")
    private Long courseMaterialId;
    private String url;

    @OneToOne
    @JoinColumn(
            name = "course_id",
            referencedColumnName = "courseId"
    )
    private Course course;
}

package com.trb.springboottutorial.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Course {

    @Id
    @SequenceGenerator(name = "courseSequence",
            allocationSize = 1, sequenceName = "course_sequence")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
            generator = "courseSequence")
    private Long courseId;


    private String courseTitle;
    private Integer credit;
}

TEST CLASS

package com.trb.springboottutorial.repository;

import com.trb.springboottutorial.entity.Course;
import com.trb.springboottutorial.entity.CourseMaterial;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class CourseMaterialRepositoryTest {

    @Autowired
    private CourseMaterialRepository courseMaterialRepository;

    @Test
    public void saveCourseMaterial() {
        Course course = Course.builder()
                .courseTitle("Daily Code Buffer")
                .credit(8)
                .build();

        CourseMaterial courseMaterial =
                CourseMaterial.builder()
                        .url("www.dailycodebuffer.com")
                        .course(course) //object references an unsaved transient instance 
                        .build();

        courseMaterialRepository.save(courseMaterial);
    }


}

SOLUTION: ADD CascadeType attribute in the CourseMaterial.class

AFTER CODE FIX

package com.trb.springboottutorial.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CourseMaterial {

    @Id
    @SequenceGenerator(name = "materialSequence",sequenceName = "material_sequence",
                        allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "materialSequence")
    private Long courseMaterialId;
    private String url;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(
            name = "course_id",
            referencedColumnName = "courseId"
    )
    private Course course;
}


Happy Learning πŸ™‚

Configure Windows Local GIT repository in Spring Cloud Config Server

My pom.xml for Spring Cloud Config Server Project springbootconfigserver

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.5</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.springboot.configserver</groupId>
	<artifactId>springbootconfigserver</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springbootconfigserver</name>
	<description>Demo project for Spring Boot Config Server</description>
	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>2021.0.4</spring-cloud.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-server</artifactId>
		</dependency>
	</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>


Step 1:  Add @EnableConfigServer annotation in the Spring Boot Application source.

@SpringBootApplication
@EnableConfigServer
public class SpringbootconfigserverApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootconfigserverApplication.class, args);
	}

}




Step 2:  Create a Local GIT repository with the application.properties

Make a note of the directory path to the GIT repository which you created locally.  

My local GIT Repository path is:  C:\Java\projects\microservices\git\configserverrepo
Application properties file in my local GIT is:  C:\Java\projects\microservices\git\configserverrepo\application.properties


Step 3:  Configure the Local GIT repository directory which contains my application.properties file in my Spring Cloud Config Server Project "springbootconfigserver"


springbootconfigserver > src > main > resources > application.properties

server.port=8084
spring.cloud.config.server.git.uri=file://c:/sarwan/java/projects/microservices/git/configserverrepo



Done!

What is Microservice?

Microservice is meant to convert large software into a number of pieces. Each piece focuses on a particular point of business. It is just like a little service with a microscopic scope for a specific target, compared to existing monolithic applications where the scope is very broad.

So, it divides the monolithic application into smaller microservices and manages and deploys these services as a single business goal; communication across these distributed services is a difficult task for developers. Use Spring Cloud to simplify integration between these distributed services.

As core Spring concepts are applied to application architecture, Spring enables a separation of concerns between the application components, such as loose coupling, which means the effect of the change is isolated, and tight cohesion, which means the code performs a single, well-defined task. Similarly, microservices exhibit the same strengths, that is, loose coupling between the collaborating services of the application, and you can change these services independently. Another strength is tight cohesion, which means an application service that deals with a single view of data; it also known as Bounded Contexts or Domain-driven design (DDD).

Advantages of Microservices:

These are following advantages if you are using the microservice architecture in your application:

  • Smaller code bases are easy to maintain
  • Easy to scale means you can scale individual components
  • Technology diversity means you can use mix libraries, frameworks, data storage, and languages
  • Fault isolation means component failure should not bring the whole system down
  • Better support for smaller, parallel teams
  • Independent deployment
  • Reduced team size also reduces the overhead associated with keeping a team focused and moving in one direction.

Disadvantages of Microservices:

Even though we have a lot of benefits with the microservices, it also has some challenges. Let’s see:

  • Difficulty to achieve strong consistency across services, such as maintaining ACID transactions within multiple processes
  • Because of distributed system, it’s harder to debug/trace
  • Greater need for end-to-end testing
  • How applications are developed and deployed
  • Communication across services and service-to-service calls

How do multiple microservices find each other? Solution: service discovery.

How do we decide which instance of a service to use? Solution: client-side load balancing.

What happens if a particular microservice is not responding? Solution: Fault Tolerance

How do we control the access of a microservice, such as providing security and rate limits? Solution: Service Security

How do multiple microservices communicate with each other? Solution: Messaging

Spring Cloud comes into the picture to provide the solution to all these challenges. Spring Cloud makes the development of distributed microservices quite practical by using leverage capabilities of the auto-configuration.

Spring Boot makes for easy development with the microservices:

  • You can create numerous services by using Spring Boot
  • You can expose resources via RestController
  • You can also consume these remote services using RestTemplate

Spring Cloud leverages capabilities for continuous deployment, rolling upgrades of new versions of code, quick rollback in case of defects, and running multiple versions of the same service at the same time.

@LoadBalanced RestTemplate in SpringBoot

How it works?

The RestTemplate bean will be intercepted and auto-configured by Spring Cloud (due to the @LoadBalanced annotation) to use a custom HttpRequestClient that uses Netflix Ribbon to do the microservice lookup. Ribbon is also a load balancer, so if you have multiple instances of a service available, it picks one for you. (Neither Eureka nor Consul on their own performs load balancing, so we use Ribbon to do it instead.)

The loadBalancer takes the logical service name (as registered with the discovery server) and converts it to the actual hostname of the chosen microservice. A RestTemplate instance is thread-safe and can be used to access any number of services in different parts of your application.

The @LoadBalanced annotation tells Spring Boot to customize RestTemplate with ClientHttpRequestFactory that does a Eureka lookup before making the HTTP call. To make this work, you’ll need to add a new config setting to application.properties:

ribbon.http.client.enabled=true 

Write a program using Java Stream to find frequency of each character in a given string.

String data = "saravanan";
Map mapdata = Arrays.stream(data.split(""))
        .collect(
                Collectors.groupingBy(Function.identity(), Collectors.counting())
        );
System.out.println(mapdata);

Output:

{a=4, r=1, s=1, v=1, n=2}

What are the dependency JARs inside spring-boot-starter?

[INFO] +- org.springframework.boot:spring-boot-starter:jar:2.7.3:compile
[INFO] | +- org.springframework.boot:spring-boot:jar:2.7.3:compile
[INFO] | | – org.springframework:spring-context:jar:5.3.22:compile
[INFO] | | +- org.springframework:spring-aop:jar:5.3.22:compile
[INFO] | | +- org.springframework:spring-beans:jar:5.3.22:compile
[INFO] | | – org.springframework:spring-expression:jar:5.3.22:compile
[INFO] | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.7.3:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-logging:jar:2.7.3:compile
[INFO] | | +- ch.qos.logback:logback-classic:jar:1.2.11:compile
[INFO] | | | – ch.qos.logback:logback-core:jar:1.2.11:compile
[INFO] | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.17.2:compile
[INFO] | | | – org.apache.logging.log4j:log4j-api:jar:2.17.2:compile
[INFO] | | – org.slf4j:jul-to-slf4j:jar:1.7.36:compile
[INFO] | +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile
[INFO] | +- org.springframework:spring-core:jar:5.3.22:compile
[INFO] | | – org.springframework:spring-jcl:jar:5.3.22:compile
[INFO] | – org.yaml:snakeyaml:jar:1.30:compile

This Class [Entity] does not define an IdClass

Scenario: I have ‘Report’ table & a ‘Transaction’ table. The primary key column in the ‘Transaction’ table is nothing but the foreign key reference of the primary key column in the ‘Report’ table

Table1: Report

=====

ReportId (PK)

ReportName

Table2: Transaction

=======

TransactionId (PK) (Also having foreign key (FK) reference to Report :: ReportId)

Solution:

Entity class for “Report” table

@Entity
@Table(name = "report")
public class Report implements Serializable {
      private static final long serialVersionUID = 1L;

      @Id
      @GeneratedValue(strategy=GenerationType.IDENTITY)
      @Column(name = "reportid")
      Integer reportId;

      @Column(name = "reportname")
      String reportName;
}

Entity class for “Transaction” table

@Entity
@Table(name = "transaction")
@IdClass(TransactionFKReportId.class)
public class Transaction implements Serializable {
     private static final long serialVersionUID = 1L;

     @Id
     Integer transactionId;
}

IdClass definition for the Transaction entity

public class TransactionFKReportId implements Serializable {
     private static final long serialVersionUID = 1L;

     @Id
     @JoinColumn(table = "report", name = "reportid")
     @Column(name = "transactionId")
     Integer transactionId;
}

Happy Learning πŸ™‚

How to launch Swagger in Spring Boot?

My Pom.xml – Add the springfox dependencies

 

<?xml version=”1.0″ encoding=”UTF-8″?>
<project xmlns=”http://maven.apache.org/POM/4.0.0&#8243;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221;
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”&gt;
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath /> <!– lookup parent from repository –>
</parent>
<groupId>com.example.platform</groupId>
<artifactId>sivaji-platform-swagger</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>sivaji-platform-swagger</name>
<description>Swagger Spec</description>

<properties>
<java.version>1.8</java.version>
<swagger.version>2.9.2</swagger.version>
<swagger-annotations.version>1.5.21</swagger-annotations.version>
<swagger-models.version>1.5.21</swagger-models.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger-annotations.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${swagger-models.version}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

 

SpringBoot Main():

 

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@SuppressWarnings(“deprecation”)
@SpringBootApplication
@ComponentScan({“com.example.platform.controller”})
public class ExamplePlatformSwaggerApplication extends WebMvcConfigurerAdapter{

public static void main(String[] args) {
SpringApplication.run(ExamplePlatformSwaggerApplication.class, args);
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(“swagger-ui.html”)
.addResourceLocations(“classpath:/META-INF/resources/”);

registry.addResourceHandler(“/webjars/**”)
.addResourceLocations(“classpath:/META-INF/resources/webjars/”);
}
}

 

SpringFoxConfig.java

 

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SpringFoxConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}

 

 

My Rest Controller Java

 

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.platform.model.Greeting;

@RestController
public class SwaggerController {

private static final String template = “Hello, %s!”;
private final AtomicLong counter = new AtomicLong();

@GetMapping(“/greeting”)
public Greeting greeting(@RequestParam(value = “name”, defaultValue = “World”) String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}

 

 

 

My Model class

 

package com.example.platform.model;

public class Greeting {

private final long id;
private final String content;

public Greeting(long id, String content) {
this.id = id;
this.content = content;
}

public long getId() {
return id;
}

public String getContent() {
return content;
}
}

 

Happing Learning πŸ™‚

Design a site like this with WordPress.com
Get started