- Swagger UI is an interactive web page that displays your REST API and lets you call it directly from the browser.
- It is used so that developers and testers can explore endpoints, send real requests and see real responses without Postman.
- It reads the OpenAPI document (
/v3/api-docs) and builds a clickable page from it automatically. - In Spring Boot, the springdoc library serves Swagger UI at
/swagger-ui.htmlwith no extra code.
Features
- Lists all endpoints, grouped by tag, with their methods and URLs.
- Try it out button sends a real request to your running application.
- Pre-filled request bodies, with a dropdown of example payloads.
- Shows the response body, status code, headers and a ready-made
curlcommand. - Displays the data model (schema) of each request and response.
- Needs no separate tool or installation.
Annotations that shape what Swagger UI shows
@Tagnames and describes a group of endpoints.@Operationgives each endpoint a summary and description.@ApiResponselists the status codes an endpoint can return.@Parameterdescribes a path variable or query parameter, with an example value.@ExampleObjectadds a ready-made request body to the dropdown in Swagger UI.@Schemadescribes each field of the model and its example value.
Hands-on Experiment: Creating a spring boot application to understand how REST API endpoints can be formally described using the Swagger UI.
The following steps are involved in developing this hands-on experiment.
Step 1: Generate the Project
Step 2: Project Structure
Step 3: pom.xml
Step 4: application.properties
Step 5: Create Entity Class
Step 6: Create Repository Interface
Step 7: Create Service Class
Step 8: Create Controller Class
Step 9: Main Application Class
Step 10: Run the Main Application Class
Step 1: Configure the Project on Spring Initializr
Go to start.spring.io and set:
- Project: Maven
- Language: Java
- Spring Boot version: 3.2.x
- Group: com.example
- Artifact: swaggerdemo
- Name: swaggerdemo
- Package name: com.example.swaggerdemo
- Packaging: Jar
- Java: 17
- Dependencies: Spring Web, Spring Data JPA, MySQL Driver, SpringDoc OpenAPI.
Click Generate to download the ZIP, then extract and import it into your IDE as a Maven project.
Step 2: Generated Project Structure

Step 3: Explore pom.xml
<?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.5</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>student-swagger-demo</artifactId>
<version>1.0.0</version>
<name>student-swagger-demo</name>
<description>Student CRUD operations explored and executed through Swagger UI</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.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- OpenAPI document generator + Swagger UI web page -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4. application.properties
spring.application.name=student-swagger-demo
server.port=8081
# MySQL (database is created automatically if it does not exist) - change username/password as needed
spring.datasource.url=jdbc:mysql://localhost:3306/studentdb?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
# ---------- Swagger UI settings ----------
# Address of the Swagger UI page
springdoc.swagger-ui.path=/swagger-ui.html
# Address of the OpenAPI document that Swagger UI reads
springdoc.api-docs.path=/v3/api-docs
# Show the "Try it out" button on every endpoint
springdoc.swagger-ui.try-it-out-enabled=true
# Show how long each executed request took
springdoc.swagger-ui.display-request-duration=true
# Expand operations of each tag when the page opens (none | list | full)
springdoc.swagger-ui.doc-expansion=list
# Sort tags alphabetically and operations in the order of the methods in the code
springdoc.swagger-ui.tags-sorter=alpha
springdoc.swagger-ui.operations-sorter=methodCode language: PHP (php)
Step 5: Create Entity Class
package com.example.swaggerdemo.entity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Schema(description = "Student details")
@Entity
@Table(name = "students")
public class Student {
@Schema(description = "Auto-generated student id", example = "1", accessMode = Schema.AccessMode.READ_ONLY)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Schema(description = "Full name of the student", example = "Ravi Kumar")
private String name;
@Schema(description = "Unique email address", example = "ravi@mail.com")
@Column(unique = true)
private String email;
@Schema(description = "Department of the student", example = "CSE")
private String department;
public Student() {
}
public Student(String name, String email, String department) {
this.name = name;
this.email = email;
this.department = department;
}
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getDepartment() { return department; }
public void setDepartment(String department) { this.department = department; }
}
Step 6: Create below Repository Interface
package com.example.swaggerdemo.repository;
import com.example.swaggerdemo.entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
boolean existsByEmail(String email);
}
Step 7: Create below Service class
package com.example.swaggerdemo.service;
import com.example.swaggerdemo.entity.Student;
import com.example.swaggerdemo.repository.StudentRepository;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;
import java.util.List;
@Service
public class StudentService {
private final StudentRepository studentRepository;
public StudentService(StudentRepository studentRepository) {
this.studentRepository = studentRepository;
}
public Student addStudent(Student student) {
if (studentRepository.existsByEmail(student.getEmail())) {
throw new ResponseStatusException(HttpStatus.CONFLICT,
"Email already registered: " + student.getEmail());
}
return studentRepository.save(student);
}
public List<Student> getAllStudents() {
return studentRepository.findAll();
}
public Student getStudentById(Long id) {
return studentRepository.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND,
"Student not found with id: " + id));
}
public Student updateStudent(Long id, Student updated) {
Student existing = getStudentById(id);
existing.setName(updated.getName());
existing.setDepartment(updated.getDepartment());
return studentRepository.save(existing);
}
public void deleteStudent(Long id) {
if (!studentRepository.existsById(id)) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND,
"Student not found with id: " + id);
}
studentRepository.deleteById(id);
}
}
Step 8: Create Controller class
package com.example.swaggerdemo.controller;
import com.example.swaggerdemo.entity.Student;
import com.example.swaggerdemo.service.StudentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "Student", description = "Create, read, update and delete students")
@RestController
@RequestMapping("/students")
public class StudentController {
private final StudentService studentService;
public StudentController(StudentService studentService) {
this.studentService = studentService;
}
// CREATE - Swagger UI shows a dropdown with these ready-made request bodies
@Operation(summary = "Create a student", description = "Creates a student. The email must be unique.")
@io.swagger.v3.oas.annotations.parameters.RequestBody(
content = @Content(mediaType = "application/json", examples = {
@ExampleObject(name = "CSE student",
value = "{\"name\":\"Ravi Kumar\",\"email\":\"ravi@mail.com\",\"department\":\"CSE\"}"),
@ExampleObject(name = "ECE student",
value = "{\"name\":\"Sita Devi\",\"email\":\"sita@mail.com\",\"department\":\"ECE\"}")
}))
@ApiResponses({
@ApiResponse(responseCode = "201", description = "Student created"),
@ApiResponse(responseCode = "409", description = "Email already registered", content = @Content)
})
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Student addStudent(@RequestBody Student student) {
return studentService.addStudent(student);
}
// READ ALL
@Operation(summary = "Get all students")
@ApiResponse(responseCode = "200", description = "List of all students")
@GetMapping
public List<Student> getAllStudents() {
return studentService.getAllStudents();
}
// READ ONE
@Operation(summary = "Get a student by id")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Student found"),
@ApiResponse(responseCode = "404", description = "Student not found", content = @Content)
})
@GetMapping("/{id}")
public Student getStudentById(
@Parameter(description = "Id of the student", example = "1") @PathVariable Long id) {
return studentService.getStudentById(id);
}
// UPDATE
@Operation(summary = "Update a student", description = "Updates name and department of an existing student")
@io.swagger.v3.oas.annotations.parameters.RequestBody(
content = @Content(mediaType = "application/json", examples = {
@ExampleObject(name = "Move to IT",
value = "{\"name\":\"Ravi Reddy\",\"email\":\"ravi@mail.com\",\"department\":\"IT\"}")
}))
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Student updated"),
@ApiResponse(responseCode = "404", description = "Student not found", content = @Content)
})
@PutMapping("/{id}")
public Student updateStudent(
@Parameter(description = "Id of the student", example = "1") @PathVariable Long id,
@RequestBody Student student) {
return studentService.updateStudent(id, student);
}
// DELETE
@Operation(summary = "Delete a student")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Student deleted"),
@ApiResponse(responseCode = "404", description = "Student not found", content = @Content)
})
@DeleteMapping("/{id}")
public String deleteStudent(
@Parameter(description = "Id of the student", example = "1") @PathVariable Long id) {
studentService.deleteStudent(id);
return "Student deleted with id: " + id;
}
}
Step 9: Main Application
package com.example.swaggerdemo;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@OpenAPIDefinition(
info = @Info(
title = "Student CRUD API",
version = "1.0",
description = "Explore and execute Student CRUD operations from the Swagger UI page"
)
)
@SpringBootApplication
public class SwaggerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SwaggerDemoApplication.class, args);
}
}
Step 10: Run the SwaggerDemoApplication



