Swagger is a very popular service documentation tool. We can use this to generate robust service documentation with very minimal configuration. This is very useful when we need to share our APIs with others for integration.

In this article, we will learn about how to configure swagger on our spring boot application and how to customize it according to our requirements.

We will create a JPA RESTful CRUD service for the Student entity. We will use the H2 database to store the Student entity details. We will use the Spring Data JPA library to perform CRUD operation.

Add the Maven dependencies

Create a new Spring Boot application and add spring-boot-starter-web, lombok(To reduce boiler plate code), spring-boot-starter-data-jpa, and h2 dependencies.

The next step is to add the Maven dependencies for swagger and swagger-ui libraries. Add the mentioned dependencies to the spring boot application’s pom.xml file.

<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger2</artifactId>
	<version>2.9.2</version>
</dependency>
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger-ui</artifactId>
	<version>2.9.2</version>
</dependency>

This will add the required swagger java libraries into our application’s classpath.

Configure the Swagger

The next step is to set up the swagger by creating a swagger configuration class.

Create a class called SwaggerConfiguration.java and define the required beans.

SwaggerConfiguration.java

package com.asb.example;

import java.time.LocalDate;

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

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

@EnableSwagger2
@Configuration
public class SwaggerConfiguration {

	@Bean
	public Docket asbApi() {
		return new Docket(DocumentationType.SWAGGER_2)
				.select()
				.apis(RequestHandlerSelectors.basePackage("com.asb.example"))
				.paths(PathSelectors.any()).build()
				.pathMapping("/")
				.directModelSubstitute(LocalDate.class, String.class)
				.genericModelSubstitutes(ResponseEntity.class)
				.useDefaultResponseMessages(false)
				.apiInfo(apiInfo())
				.enableUrlTemplating(true);
	}
	
	@Bean
	public ApiInfo apiInfo() {
		return new ApiInfoBuilder()
				.description("Student Service List")
				.title("Student Service")
				.license("ASB Notebook")
				.licenseUrl("https://asbnotebook.com")
				.contact(contact())
				.build();
	}
	
	@Bean
	public Contact contact() {
		return new Contact("Arun", "http://asbnotebook.com", "asbnotebook@gmail.com");
	}
}

We have used @EnableSwagger2 annotation to enable swagger documentation in our application.

We have defined a Docket bean, which is a builder for swagger configuration. It provides different configuration options that can be used to set up the swagger documentation.

We have added some basic setup like API packages, API info details, etc. There are a lot of other options available, that can be used to customize the swagger documentation configuration.

We have also defined ApiInfo and Contact beans to setup information like API license details, contact details, etc.

Create required classes and configuration for JPA CRUD operation

As we are going to create JPA CRUD operation to demonstrate this swagger integration example, we need to create required classes, interfaces and configuration.

Setup H2 database configurations

Add the mentioned yml configuration details into application.yml(we can use application.properties file instead) file of the application.

spring:
  datasource:
    url: jdbc:h2:~/asbdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
    data-username: sa
    data-password:
    data: classpath:/data.sql
  h2:
    console:
      enabled: true
      path: /h2-db-console
      settings:
        trace: true

Create a data.sql file under src/main/resources/ directory, to create the required Student table on the H2 database on application startup.

DROP TABLE IF EXISTS STUDENT;

CREATE TABLE STUDENT(
	STUDNT_ID BIGINT PRIMARY KEY, 
	NAME VARCHAR(50),
	GRADE VARCHAR(2)
);

Create a Student Entity class

Create a Student.java entity class. We are going to perform CRUD operation using JPA.

package com.asb.example.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
@ApiModel(description="Student Model class",value="Student Model")
public class Student {

	@ApiModelProperty(dataType="Long", required=true, name="Student Id", value="1")
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long studntId;
	
	@ApiModelProperty(dataType="String", required=true, name="Student Name", value="Arun")
	private String name;
	
	@ApiModelProperty(dataType="String", required=true, name="Grade", value="XI")
	private String grade;
}

Swagger supports Model-level annotations, which we can see from the above Student.java class.

@ApiModel

This class level annotation indicates that this class should be considered as API model type. This annotation also indicates that the class is used as the API request/response parameter in API operations.

@ApiModelProperty

This is a field-level swagger configuration annotation. We can use this annotation to set the default value, datatype should be shown on the swagger document, etc.

The below image shows the result of our above swagger configuration.

swagger api model property example

Create a Student Repository interface

Create a StudentRepository.java interface as shown below. Since we are extending the JpaRepository interface, we get all the required CRUD functionalities out of the box.

package com.asb.example.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.asb.example.model.Student;

public interface StudentRepository extends JpaRepository<Student, Long> {

}

Create a service class

Create a StudentService.java class to implement service layer.

package com.asb.example.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.asb.example.model.Student;
import com.asb.example.repository.StudentRepository;

@Service
public class StudentService {
	
	@Autowired
	private StudentRepository studentRepository;
	
	public List<Student> getAllStudents(){
		return studentRepository.findAll();
	}
	
	public Student saveStudent(Student student){
		return studentRepository.save(student);
	}
	
	public Student updateStudent(Student student){
		return studentRepository.save(student);
	}
	
	public Student deleteStudent(Long studentId){
		Student student = studentRepository.getOne(studentId);
		studentRepository.delete(student);
		return student;
	}
}

If you need more details about JPA CRUD operation, check out this article.

Configuring Swagger for REST end points

We have configured API Model with swagger before. Now it is the major part of the swagger configuration. Since we are creating documentation for REST endpoints, we need to create a Restful controller layer and configure them with swagger annotations.

Set up swagger configuration messages

Update the application.yml file by adding these configuration properties. We are adding a few swagger messages to configuration file(application.yml) and setting the application context path to /students.

server:
  servlet:
    context-path: /students
StudentController:
    findStudents: Find All Studen Details.
    saveStudent: Save Student Details.
    updateStudent: Update Student Details.
    deleteStudentById: Delete Student Details by ID.

Create a RestController class

Next, we will create a REST controller and add CRUD operation endpoints.

Create StudentController.java class and add the following content.

package com.asb.example.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RestController;

import com.asb.example.model.Student;
import com.asb.example.service.StudentService;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

@RestController
public class StudentController {

	@Autowired
	private StudentService studentService;

	@ApiOperation(value = "Find Students", notes = "${StudentController.findStudents}")
	@GetMapping("/students")
	public ResponseEntity<List<Student>> getAllStudents() {
		return new ResponseEntity<>(studentService.getAllStudents(), HttpStatus.OK);
	}

	@ApiOperation(value = "Save Student", notes = "${StudentController.saveStudent}")
	@PostMapping("/students")
	public ResponseEntity<Student> saveStudent(
			@ApiParam(name = "Save Student", value = "Student Details to be saved", required = true) @RequestBody Student student) {
		return new ResponseEntity<>(studentService.saveStudent(student), HttpStatus.CREATED);
	}

	@ApiOperation(value = "Update Students", notes = "${StudentController.updateStudents}")
	@ApiResponses(value = { @ApiResponse(code = 200, message = "Successfully Saved"),
			@ApiResponse(code = 401, message = "You are not authorized to view the resource"),
			@ApiResponse(code = 403, message = "Accessing the resource is forbidden"),
			@ApiResponse(code = 404, message = "The resource is not found") })
	@PutMapping("/students")
	public ResponseEntity<Student> updateStudent(
			@ApiParam(name = "Update Student", value = "Student Details to be updated", required = true) @RequestBody Student student) {
		return new ResponseEntity<>(studentService.updateStudent(student), HttpStatus.CREATED);
	}

	@ApiOperation(value = "Delete Student By ID", notes = "${StudentController.deleteStudentById}")
	@DeleteMapping("/student/{student-id}")
	public ResponseEntity<Student> deleteStudent(
			@ApiParam(name = "Delete Student", value = "Id of Student to be deleted", required = true) @PathVariable(name = "student-id") Long studentId) {
		return new ResponseEntity<>(studentService.deleteStudent(studentId), HttpStatus.OK);
	}
}

Here, we have used a few of the swagger configuration annotations. We will discuss the usage of them one by one.

@ApiOperation

This annotation can be used to describe a particular endpoint’s operation. We have set the value and notes fields of the API. Notice that we are reading the notes field values from the application.yml configuration file. This is reflected in the swagger documentation as shown in the below image.

swagger ui api operation example

@ApiParam

This annotation can be used to define the required API parameters of a particular API endpoint. We can set the name, value and other supported parameters.

The below image shows the result of our swagger API param configuration.

swagger ui api param example

@ApiResponses

We can specify expected response details for a particular API by using this annotation. We can pass multiple @ApiResponse annotations as a value field as shown in the above example.

The below image shows the generated swagger documentation for the above configuration.

swagger ui api response example

Time to run the application

It’s time to test our swagger configuration. 🙂 Run the spring boot application.

swagger ui example

We can test the application endpoints by clicking on the Try it out button.

swagger example

Enter the student details and click on the Execute button.

swagger example

We can see the student details saved successfully in the response.

swagger ui example

Congratulations! We have successfully configured Swagger documentation for our Spring boot application.

Conclusion

In this article, we learned how to configure swagger for spring boot applications. We learned about different API operation-level and API model-level annotations.

We also learned how to use Swagger UI to test the endpoints.

Complete working code is available on GitHub. Happy coding! 🙂

You may also interested in