In this blog post, we’ll explore the process of generating an OpenAPI YAML file for an existing REST API within a Spring Boot application. The OpenAPI YAML file serves as a critical interface bridging the implementation of the REST API and its consuming applications. It plays a pivotal role in creating comprehensive REST API documentation through the Swagger user interface. Spring Boot provides robust support for automatically generating the OpenAPI YAML file, given that the Spring Boot REST API is already developed and operational. Join us as we delve into obtaining the OpenAPI YAML file within your existing Spring Boot application.
Create a Spring Boot Application
To start the generation of an OpenAPI YAML file, the first step involves creating a Spring Boot web application designed to execute REST APIs. For illustration purposes, we have established a REST API utilizing the GET, POST, and PUT methods. Begin by crafting a Spring Boot application, incorporating the ‘spring-boot-starter-web’ dependency to facilitate the process.
Create dependency for OpenAPI yaml file generation
In order to generate the OpenAPI YAML file, the Spring Boot dependency ‘spring-boot-starter-web’ is essential. Additionally, you must include the ‘springdoc-openapi-starter-webmvc-api’ dependency in the ‘pom.xml’ file. This dependency plays a crucial role in generating and exposing the OpenAPI YAML file within the Spring Boot application.
The complete ‘pom.xml’ file will resemble the following. This ‘pom.xml’ configuration includes the necessary dependencies, including ‘spring-boot-starter-web’ and ‘springdoc-openapi-ui’, required for OpenAPI YAML file generation within your Spring Boot application.
<?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>3.2.2</version> <relativePath /> <!-- lookup parent from repository --> </parent> <groupId>com.yawintutor</groupId> <artifactId>SpringbootOpenAPI</artifactId> <version>0.0.1-SNAPSHOT</version> <name>SpringbootOpenAPI</name> <description>Spring Boot Open API 3</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Create the Rest API controller class
Below is an example of a Rest Controller class. The class is annotated with @RestController
and contains four REST API methods. These methods uses HTTP methods such as GET, POST, and PUT.
This controller demonstrates the usage of @RestController
annotation to define a REST controller in Spring. The @GetMapping
, @PostMapping
and @PutMapping
annotations are used to map the methods to corresponding HTTP GET, POST, and PUT requests, respectively.
package com.yawintutor; import java.util.Collection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/employee") public class EmployeeController { @Autowired EmployeeService service; @GetMapping("/{id}") public Employee findById(@PathVariable int id) { return service.findById(id); } @GetMapping("/") public Collection findEmployees() { return service.findEmployees(); } @PostMapping("/{id}") @ResponseStatus(HttpStatus.OK) public Employee addEmployee(@RequestBody final Employee employee) { return service.add(employee); } @PutMapping("/{id}") @ResponseStatus(HttpStatus.OK) public Employee updateEmployee(@PathVariable("id") final int id, @RequestBody final Employee employee) { return service.update(id, employee); } }
Spring Boot Service class
Below is an example of a Spring Boot service class that handles REST API methods. It includes implementations for managing instances of the Employee
class. The service methods encompass functionalities such as fetching an employee by ID, retrieving all employees in the list, adding a new employee to the list, and updating an existing employee. The code snippet below illustrates the Spring Boot service class annotated with @Service
.
package com.yawintutor; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.springframework.stereotype.Service; @Service public class EmployeeService { private static List list = new ArrayList(); static { list.add(new Employee(1, "Kim")); list.add(new Employee(2, "Kalai")); list.add(new Employee(3, "White")); } public Employee findById(int id) { for (Employee employee : list) { if (employee.getId() == id) return employee; } return null; } public Collection findEmployees() { return list; } public Employee add(Employee employee) { list.add(employee); return employee; } public Employee update(int id, Employee emp) { for (Employee employee : list) { if (employee.getId() == id) { employee.setName(emp.getName()); return employee; } } return null; } }
Create Model Class
In this example, the Employee
class serves as a Plain Old Java Object (POJO) designed to encapsulate employee details. The Employee
class comprises two attributes along with corresponding getter and setter methods. Below is a sample implementation of the Employee
POJO class:
package com.yawintutor; public class Employee { private int id; private String name; public Employee(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
The Employee
class is a basic representation of an employee entity, featuring attributes such as id
and name
. It includes constructors to initialize object instances with or without parameters, along with getter and setter methods for accessing and modifying the attributes. This POJO class facilitates the structured organization and manipulation of employee data within the Spring Boot application.
How to generate the Open API document?
Once you’ve incorporated all the aforementioned classes and configurations into your project, you can proceed to start the Spring Boot application. By default, the Spring Boot application will run on port 8080.
The following URL serves as the default endpoint for generating the OpenAPI yaml content. Simply access this URL in your browser to view the OpenAPI documentation:
http://localhost:8080/v3/api-docs
How to download the open-api.yaml file
To download the OpenAPI YAML file by default, you can access the following URL in your browser:
http://localhost:8080/v3/api-docs.yaml
Upon invoking this URL, the browser will automatically trigger the download of the OpenAPI YAML file (open-api.yaml
), providing you with a local copy of the documentation. This simple approach allows users to access and save the OpenAPI documentation conveniently from their browser interface.
Conclusion
This post focuses on generating an OpenAPI document and the OpenAPI YAML file for an existing REST API within a Spring Boot application. It elucidates the default URL for invoking the OpenAPI YAML file as demonstrated in the example. By following the steps outlined, developers can effortlessly access and utilize the OpenAPI documentation to enhance the functionality and accessibility of their Spring Boot applications.
The sample open-api yaml file will look like below.
{ "openapi": "3.0.1", "info": { "title": "OpenAPI definition", "version": "v0" }, "servers": [ { "url": "http://localhost:8080", "description": "Generated server url" } ], "paths": { "/employee/{id}": { "get": { "tags": [ "employee-controller" ], "operationId": "findById", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int32" } } ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/Employee" } } } } } }, "put": { "tags": [ "employee-controller" ], "operationId": "updateEmployee", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer", "format": "int32" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Employee" } } }, "required": true }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/Employee" } } } } } }, "post": { "tags": [ "employee-controller" ], "operationId": "addEmployee", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Employee" } } }, "required": true }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/Employee" } } } } } } }, "/employee/": { "get": { "tags": [ "employee-controller" ], "operationId": "findEmployees", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Employee" } } } } } } } } }, "components": { "schemas": { "Employee": { "type": "object", "properties": { "id": { "type": "integer", "format": "int32" }, "name": { "type": "string" } } } } } }