{{announcement.body}}
{{announcement.title}}

OpenAPI 3 Documentation With Spring Boot

DZone 's Guide to

OpenAPI 3 Documentation With Spring Boot

In this tutorial, we are going to try out a Spring Boot Open API 3-enabled REST project and explore some of its capabilities.

· Java Zone ·
Free Resource

In this tutorial, we are going to try out a Spring Boot Open API 3-enabled REST project and explore some of its capabilities. Springdoc-openapi java library is fast becoming very compelling.

We are going to refer to https://spring.io/guides/gs/rest-service/ and https://springdoc.org/.

Prerequisites:

  • Java 8.x.
  • Maven 3.x.

Steps

Start by creating a Maven JAR project. Below, you will see the pom.xml to use:

XML
 




xxxxxxxxxx
1
56


 
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0"
3
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5
    <modelVersion>4.0.0</modelVersion>
6
    <parent>
7
        <groupId>org.springframework.boot</groupId>
8
        <artifactId>spring-boot-starter-parent</artifactId>
9
        <version>2.2.2.RELEASE</version>
10
        <relativePath ></relativePath> <!-- lookup parent from repository -->
11
    </parent>
12
    <groupId>com.example</groupId>
13
    <artifactId>sample</artifactId>
14
    <version>0.0.1</version>
15
    <name>sample</name>
16
    <description>Demo project for Spring Boot with 
17
    openapi 3 documentation</description>
18
 
          
19
    <properties>
20
        <java.version>1.8</java.version>
21
    </properties>
22
 
          
23
    <dependencies>
24
        <dependency>
25
            <groupId>org.springframework.boot</groupId>
26
            <artifactId>spring-boot-starter-web</artifactId>
27
        </dependency>
28
        <dependency>
29
            <groupId>org.springdoc</groupId>
30
            <artifactId>springdoc-openapi-ui</artifactId>
31
            <version>1.2.32</version>
32
        </dependency>
33
        
34
        <dependency>
35
            <groupId>org.springframework.boot</groupId>
36
            <artifactId>spring-boot-starter-test</artifactId>
37
            <scope>test</scope>
38
            <exclusions>
39
                <exclusion>
40
                    <groupId>org.junit.vintage</groupId>
41
                    <artifactId>junit-vintage-engine</artifactId>
42
                </exclusion>
43
            </exclusions>
44
        </dependency>
45
    </dependencies>
46
 
          
47
    <build>
48
        <plugins>
49
            <plugin>
50
                <groupId>org.springframework.boot</groupId>
51
                <artifactId>spring-boot-maven-plugin</artifactId>
52
            </plugin>
53
        </plugins>
54
    </build> 
55
 
          
56
</project>



Note the "springdoc-openapi-ui" dependency and "springdoc-openapi-maven-plugin" plugin.

Now, let's create a small Java bean class. 

Java
 




xxxxxxxxxx
1
91


 
1
package sample;
2
 
          
3
import javax.validation.constraints.Email;
4
import javax.validation.constraints.Max;
5
import javax.validation.constraints.Min;
6
import javax.validation.constraints.NotBlank;
7
import javax.validation.constraints.NotNull;
8
import javax.validation.constraints.Pattern;
9
import javax.validation.constraints.Size;
10
import javax.xml.bind.annotation.XmlAccessType;
11
import javax.xml.bind.annotation.XmlAccessorType;
12
import javax.xml.bind.annotation.XmlRootElement;
13
 
          
14
import org.hibernate.validator.constraints.CreditCardNumber;
15
 
          
16
@XmlRootElement(name = "person")
17
@XmlAccessorType(XmlAccessType.FIELD)
18
public class Person {
19
    private long id;
20
    private String firstName;
21
    @NotNull
22
    @NotBlank
23
    private String lastName;
24
    @Pattern(regexp = ".+@.+\\..+", message = "Please provide a valid email address")
25
    private String email;
26
    @Email()
27
    private String email1;
28
    @Min(18)
29
    @Max(30)
30
    private int age;
31
    @CreditCardNumber
32
    private String creditCardNumber;
33
 
          
34
    public String getCreditCardNumber() {
35
        return creditCardNumber;
36
    }
37
 
          
38
    public void setCreditCardNumber(String creditCardNumber) {
39
        this.creditCardNumber = creditCardNumber;
40
    }
41
 
          
42
    public long getId() {
43
        return id;
44
    }
45
 
          
46
    public void setId(long id) {
47
        this.id = id;
48
    }
49
 
          
50
    public String getEmail1() {
51
        return email1;
52
    }
53
 
          
54
    public void setEmail1(String email1) {
55
        this.email1 = email1;
56
    }
57
 
          
58
    @Size(min = 2)
59
    public String getFirstName() {
60
        return firstName;
61
    }
62
 
          
63
    public void setFirstName(String firstName) {
64
        this.firstName = firstName;
65
    }
66
 
          
67
    public String getLastName() {
68
        return lastName;
69
    }
70
 
          
71
    public void setLastName(String lastName) {
72
        this.lastName = lastName;
73
    }
74
 
          
75
    public String getEmail() {
76
        return email;
77
    }
78
 
          
79
    public void setEmail(String email) {
80
        this.email = email;
81
    }
82
 
          
83
    public int getAge() {
84
        return age;
85
    }
86
 
          
87
    public void setAge(int age) {
88
        this.age = age;
89
    }
90
}
91
 
          



This is an example of a Java bean. Now, let's create a controller.

Java
 




xxxxxxxxxx
1
17


 
1
package sample;
2
 
          
3
import javax.validation.Valid;
4
 
          
5
import org.springframework.web.bind.annotation.RequestBody;
6
import org.springframework.web.bind.annotation.RequestMapping;
7
import org.springframework.web.bind.annotation.RequestMethod;
8
import org.springframework.web.bind.annotation.RestController;
9
 
          
10
@RestController
11
public class PersonController {
12
    @RequestMapping(path = "/person", method = RequestMethod.POST)
13
    public Person person(@Valid @RequestBody Person person) {
14
        return person;
15
    }
16
}
17
 
          



Above is a sample REST Controller.

Let's make some entries in src\main\resources\application.properties.

Properties files
 




xxxxxxxxxx
1


 
1
application-description=@project.description@
2
application-version=@project.version@
3
logging.level.org.springframework.boot.autoconfigure=ERROR



The above entries will pass on Maven build-related information to the OpenAPI documentation.

Finally, let's write the spring boot application class

Java
 




x


1
package sample;
2
3
import org.springframework.beans.factory.annotation.Value;
4
import org.springframework.boot.SpringApplication;
5
import org.springframework.boot.autoconfigure.SpringBootApplication;
6
import org.springframework.context.annotation.Bean;
7
import org.springframework.context.annotation.ComponentScan;
8
9
import io.swagger.v3.oas.models.OpenAPI;
10
import io.swagger.v3.oas.models.info.Info;
11
import io.swagger.v3.oas.models.info.License;
12
13
@SpringBootApplication
14
public class SampleApplication {
15
    public static void main(String[] args) {
16
        SpringApplication.run(SampleApplication.class, args);
17
    }
18
    
19
    @Bean
20
    public OpenAPI customOpenAPI(@Value("${application-description}") String appDesciption, @Value("${application-version}") String appVersion) {
21
     return new OpenAPI()
22
          .info(new Info()
23
          .title("sample application API")
24
          .version(appVersion)
25
          .description(appDesciption)
26
          .termsOfService("http://swagger.io/terms/")
27
          .license(new License().name("Apache 2.0").url("http://springdoc.org")));
28
    }
29
}



Also note how the API version and description is being leveraged from application.properties.

At this stage, this is what the project looks like in Eclipse:

Initial project structure

Above are the project contents. Next, execute the mvn clean package from the command prompt or terminal. Then, execute java -jar target\sample-0.0.1.jar.

You can also launch the application by running the SampleApplication.java class from your IDE.

Now, let's visit the Swagger UI — http://localhost:8080/swagger-ui.html:

Sample application with Swagger

Click the green Post button and expand the > symbol on the right of Person under Schemas.

Schema and response

The nice thing is how the contract is automatically detailed leveraging JSR-303 annotations on the model. It out-of-the-box covers many of the important annotations and documents them. However, I did not see it support out of the box @javax.validation.constraints.Email and @org.hibernate.validator.constraints.CreditCardNumber at this point in time.

For completeness, let's post a request. Press the Try it out button.

Pressing "Try it Out" button

Press the blue execute button.

Pressing Execute button


Let's feed in a valid input:

JSON
 




xxxxxxxxxx
1


 
1
{
2
  "id": 0,
3
  "firstName": "string",
4
  "lastName": "string",
5
  "email": "abc@abc.com",
6
  "email1": "abc@abc.com",
7
  "age": 20,
8
  "creditCardNumber": "4111111111111111"
9
}



Let's feed that valid input into the Request Body Section

Feeding input to request body

On pressing the blue Execute button we see the below:

Output of execution


This was only a brief introduction to the capabilities of the dependency:

XML
 




xxxxxxxxxx
1


 
1
<dependency>
2
    <groupId>org.springdoc</groupId>
3
    <artifactId>springdoc-openapi-ui</artifactId>
4
    <version>1.2.32</version>
5
</dependency>



Troubleshooting Tips

  • Ensure prerequisites.
  • If using the Eclipse IDE, we might need to do a Maven update on the project after creating all the files.
  • In the Swagger UI, if you are unable to access the “Schema” definitions link, it might be because you need to come out of the “try it out “ mode. Click on one or two Cancel buttons that might be visible.


Source Code is here: https://github.com/teq-niq/sample/tree/springdoc-openapi-intro.
Git Clone URL: https://github.com/teq-niq/sample.git.
Branch: springdoc-openapi-intro.

Also, please read part II at https://dzone.com/articles/doing-more-with-springdoc-openapi.

Topics:
java ,open api ,rest api ,spring boot ,tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}