Creating a Microservice with Spring Boot, OpenApi and Swagger

 

Creating a Microservice with Spring Boot, OpenApi and Swagger


Microservices have become a popular architecture pattern, enabling developers to build and deploy small, independent services that can communicate with each other. Spring Boot is an excellent framework for developing microservices due to its simplicity and ease of use. Coupling Spring Boot with Swagger allows you to create robust APIs that are well-documented and easy to test. In this article, we'll walk through the steps to create a simple microservice with Spring Boot and Swagger.

springdoc-openapi-javadoc and Swagger are closely related in the context of API documentation for Spring Boot applications. Here's a breakdown of their relationship and how they work together:

Swagger and OpenAPI

  • Swagger: Originally developed by SmartBear, Swagger is a set of open-source tools built around the OpenAPI Specification (OAS), which allows developers to design, build, document, and consume REST APIs.

  • OpenAPI: The OpenAPI Specification is a standard for defining APIs, which was based on the Swagger Specification. It provides a standard way to describe the structure of APIs, making it easier to automate processes around API development.

Springdoc-OpenAPI

  • Springdoc-OpenAPI: This is a library that helps to automatically generate OpenAPI 3.0 documentation for Spring Boot projects. It scans the application at runtime and generates the OpenAPI documentation based on the annotations and structure of the code.

  • Swagger UI: As part of the Springdoc-OpenAPI ecosystem, Swagger UI is used to visualize the API documentation in a user-friendly web interface. This allows developers to explore and test the API endpoints directly from their browser.

Springdoc-OpenAPI-Javadoc

  • Springdoc-OpenAPI-Javadoc: This is an extension of the Springdoc-OpenAPI library that enhances the generated OpenAPI documentation using Javadoc comments. It extracts descriptions and other details from Javadoc comments in the source code and incorporates them into the OpenAPI documentation.

How They Work Together

  1. Generating OpenAPI Documentation:

    • Springdoc-OpenAPI generates OpenAPI documentation by scanning the Spring Boot application for annotations like @RestController, @GetMapping, @PostMapping, etc.

    • The generated OpenAPI documentation is in JSON or YAML format, conforming to the OpenAPI 3.0 specification.

  2. Enhancing with Javadoc:

    • Springdoc-OpenAPI-Javadoc reads Javadoc comments from your source code.

    • These comments provide additional context, such as method descriptions, parameter details, and return values, which are incorporated into the OpenAPI documentation.

  3. Displaying with Swagger UI:

    • The OpenAPI documentation is served at a specific endpoint (e.g., /v3/api-docs).

    • Swagger UI uses this documentation to render an interactive web page where developers can view and test the API.



Displaying with Swagger UI


Example Workflow

Prerequisites

Before we start, ensure you have the following installed:

  • Java Development Kit (JDK) 8 or higher

  • Maven

  • Your favorite IDE (IntelliJ IDEA, Eclipse, or Spring Tool Suite)

Step 1: Set Up Your Spring Boot Project

First, create a new Spring Boot project. You can do this via the Spring Initializr or directly from your IDE. Select the following dependencies:

  • Spring Web

  • Spring Boot DevTools

Project Structure

After setting up, your project structure should look something like this:

src/

└── main/

    ├── java/

    │   └── com/

    │       └── example/

    │           └── microservice/

    │               ├── controller/

    │               ├── model/

    │               ├── service/

    │               └── MicroserviceApplication.java

    └── resources/

        └── application.properties


Step 2: Create a Simple REST Controller

Next, let's create a simple REST controller that will handle HTTP requests. Create a new package controller and add a class HelloController.

package com.example.microservice.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class HelloController {

     @GetMapping("/hello/{helloId}")
      public ResponseEntity<Hello> sayHello(Long helloId) {
        if(helloId==1){
        Hello hello = new Hello();
        hello.setMessage("Hello, World!");
        return new ResponseEntity<Hello>(hello, new HttpHeaders(), HttpStatus.OK);
	}else
		return new ResponseEntity<Hello>(new HttpHeaders(), HttpStatus.NOT_FOUND);
    }
}


Step 3: Create an Home model

public class Hello{

String message;


public String getMessage(){

return message;

}

public void setMessage(String message){

this.message = message;

}

}

Step 4: Integrate OpenApi and Swagger

pom.xml should contains following dependencies and parent:

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.7.18</version>

<relativePath />

</parent>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.springdoc</groupId>

<artifactId>springdoc-openapi-ui</artifactId>

<version>1.5.10</version>

<scope>compile</scope>

</dependency>

<dependency>

<groupId>io.swagger.core.v3</groupId>

<artifactId>swagger-jaxrs2</artifactId>

<version>2.1.9</version>

</dependency>

<dependency>

<groupId>org.apache.tomcat.embed</groupId>

<artifactId>tomcat-embed-core</artifactId>

<version>9.0.91</version>

<scope>compile</scope>

</dependency>


Step 5a: Add Swagger elements to the rest controller


package com.example.microservice.controller;

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

import org.springframework.web.bind.annotation.RequestMapping;

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


import io.swagger.v3.oas.annotations.Operation;

import io.swagger.v3.oas.annotations.Parameter;

import io.swagger.v3.oas.annotations.enums.Explode;

import io.swagger.v3.oas.annotations.enums.ParameterIn;

import io.swagger.v3.oas.annotations.media.ArraySchema;

import io.swagger.v3.oas.annotations.media.Content;

import io.swagger.v3.oas.annotations.media.Schema;

import io.swagger.v3.oas.annotations.responses.ApiResponse;

import io.swagger.v3.oas.annotations.responses.ApiResponses;

import io.swagger.v3.oas.annotations.tags.Tag;


@RestController

@RequestMapping("/api")

@Tag(name = "Hello Controller", description = "Hello controller is here")

public class HelloController {


    @GetMapping("/hello/{helloId}")

    @Operation(summary = "Hello rest controller entry point")

    @ApiResponses(value = {

    @ApiResponse(responseCode = "200", description =    "Response is OK", content = {   

    @Content(mediaType = "application/json", array =  @ArraySchema(schema =  

    @Schema(implementation = HelloResponse.class)))}), 

    @ApiResponse(responseCode = "404", description = "Not Found", content = @Content) })

    public ResponseEntity<HelloResponse> sayHello(

@Parameter(

    name =  "helloId",

    example = "1,2,3 ….",

    required = true,

    description = "the hello id",

    in = ParameterIn.DEFAULT)Long helloId

) {

        if(helloId==1){

HelloResponse hello = new HelloResponse();

hello.setMessage("Hello, World!");

return new ResponseEntity<HelloResponse>(hello, new HttpHeaders(), HttpStatus.OK);

}else

return new ResponseEntity<HelloResponse>(new HttpHeaders(), HttpStatus.NOT_FOUND);

    }


@PostMapping("/hello/create/{helloId}")

@Operation(summary = "Create element hello")

@ApiResponses(value = {

@ApiResponse(responseCode = "400", description = "Error", content = @Content)})

public ResponseEntity<HelloRequest> create(

@Parameter(

    name =  "helloRequest",

    example = "",

    required = true,

description = "",

in = ParameterIn.DEFAULT,explode = Explode.TRUE)

@RequestBody HelloRequest helloRequest,

@Parameter(

    name =  "helloId",

    example = "1,2,3 ….",

    required = true,

    description = "the hello id",

    in = ParameterIn.DEFAULT)Long helloId) {


source code to save the HelloRequest

}

}

Step 5b: Add Swagger elements to the request class


@Tag(name = "HelloRequest")

public class HelloRequest{

@Parameter(allowEmptyValue = true,description = "message to send to Hello rest",example = "hello how are you?",name = "message")

String message;


public String getMessage(){

return message;

}

public void setMessage(String message){

this.message = message;

}

}


Step 6: Add other API configuration

To display personal information on the Swagger page, such as company information, add the following Spring configuration class:


import org.springframework.context.annotation.Configuration;


import io.swagger.v3.oas.annotations.OpenAPIDefinition;

import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;

import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;

import io.swagger.v3.oas.annotations.info.Contact;

import io.swagger.v3.oas.annotations.info.Info;

import io.swagger.v3.oas.annotations.security.SecurityRequirement;

import io.swagger.v3.oas.annotations.security.SecurityScheme;

import io.swagger.v3.oas.annotations.servers.Server;


/**

 * The Class OpenAPIConfiguration.

 */

@Configuration

@OpenAPIDefinition(

        info = @Info(title = "Hello API Rest", version = "2.0",

        contact = @Contact(name = "Your company name", email = "Your company email", url = "your company site url"),

        description = "API rest description …"), security = { @SecurityRequirement(name = "basic")}

@SecurityScheme(type = SecuritySchemeType.HTTP, name = "basic", in = SecuritySchemeIn.HEADER, scheme = "basic" )

public class OpenAPIConfiguration {


}


Step 7: Run Your Application

Now, run your Spring Boot application. You should be able to access your API endpoint at http://localhost:8080/api/hello/1.

To view the Swagger UI, navigate to http://localhost:8080/swagger-ui/index.html?configUrl=/hello/v3/api-docs/swagger-config. Here, you can see your API documented and test it directly from the interface.

To view the API endpoint json document:

http://localhost:8080/v3/api-docs

and the API endpoint yaml document:

http://localhost:8080/v3/api-docs.yaml


Conclusion

You've successfully created a simple microservice with Spring Boot and integrated Swagger for API documentation. This setup provides a solid foundation for building and scaling microservices. From here, you can expand your microservice by adding more endpoints, integrating with databases, and implementing advanced features.

Spring Boot and Swagger together streamline the development and documentation process, making your microservices robust and developer-friendly. 

The integration of springdoc-openapi-javadoc with Swagger and OpenAPI provides a powerful solution for API documentation in Spring Boot applications. By leveraging Javadoc comments and automated generation tools, developers can create comprehensive and interactive documentation that is easy to maintain and use. This synergy between springdoc-openapi-javadoc and Swagger enhances the overall API development process, making it more efficient and developer-friendly.

References

  1. Spring Boot Reference Documentation

  2. Springfox Swagger Documentation

  3. Creating a REST API with Spring Boot

  4. Integrating Swagger2 with Spring Boot

  5. Spring Initializr


Call to Action

Follow for more software architecture tips! Have suggestions? Share your thoughts on topics you'd like covered next.

About Me

I am passionate about IT technologies. If you’re interested in learning more or staying updated with my latest articles, feel free to connect with me on:

Feel free to reach out through any of these platforms if you have any questions!

I am excited to hear your thoughts! 👇

Comments

Popular posts from this blog

Monitoring and Logging with Prometheus: A Practical Guide

Creating a Complete CRUD API with Spring Boot 3: Authentication, Authorization, and Testing

Logging in Spring Boot 3: Best Practices for Configuration and Implementation