Building a Spring Boot CRUD API with Swagger Documentation

DevCorner - Feb 15 - - Dev Community

Introduction

Spring Boot is a powerful framework for building RESTful APIs quickly and efficiently. When building a CRUD (Create, Read, Update, Delete) API, it is crucial to document it properly so that developers can understand and interact with the API seamlessly. This is where Swagger comes in. Swagger (OpenAPI) provides an interface to visualize, interact, and test REST APIs without the need to manually write extensive documentation.

In this blog, we will build a simple CRUD API using Spring Boot and integrate Swagger for API documentation.


1. Project Setup

Maven Dependencies

Add the following dependencies to your pom.xml file:

<dependencies>
    <!-- Spring Boot Starter for Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Starter for JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- H2 Database -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>

    <!-- Swagger for API Documentation -->
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
        <version>2.2.0</version>
    </dependency>
</dependencies>
Enter fullscreen mode Exit fullscreen mode

2. Creating the Entity Class

Let's define a User entity class:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "Entity representing a User")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Schema(description = "Unique identifier of the user", example = "1", required = true)
    private Long id;

    @Column(nullable = false)
    @Schema(description = "Name of the user", example = "John Doe", required = true)
    private String name;

    @Column(nullable = false, unique = true)
    @Schema(description = "Email of the user", example = "john.doe@example.com", required = true)
    private String email;

    @Schema(description = "Role of the user", example = "Admin")
    private String role;
}
Enter fullscreen mode Exit fullscreen mode

3. Creating the Repository Interface

Create a UserRepository interface extending JpaRepository:

public interface UserRepository extends JpaRepository<User, Long> {
}
Enter fullscreen mode Exit fullscreen mode

4. Creating the Service Layer

The UserService class will handle the business logic:

@Service
public class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    public User getUserById(Long id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("User not found"));
    }

    public User createUser(User user) {
        return userRepository.save(user);
    }

    public User updateUser(Long id, User updatedUser) {
        User existingUser = getUserById(id);
        existingUser.setName(updatedUser.getName());
        existingUser.setEmail(updatedUser.getEmail());
        existingUser.setRole(updatedUser.getRole());
        return userRepository.save(existingUser);
    }

    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Creating the Controller Layer

Define REST endpoints in UserController class:

@RestController
@RequestMapping("/api/users")
@Tag(name = "User API", description = "CRUD operations for User management")
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping
    @Operation(summary = "Get all users")
    public ResponseEntity<List<User>> getAllUsers() {
        return ResponseEntity.ok(userService.getAllUsers());
    }

    @GetMapping("/{id}")
    @Operation(summary = "Get user by ID")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        return ResponseEntity.ok(userService.getUserById(id));
    }

    @PostMapping
    @Operation(summary = "Create a user")
    public ResponseEntity<User> createUser(@RequestBody User user) {
        return ResponseEntity.ok(userService.createUser(user));
    }

    @PutMapping("/{id}")
    @Operation(summary = "Update a user")
    public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
        return ResponseEntity.ok(userService.updateUser(id, user));
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "Delete a user")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}
Enter fullscreen mode Exit fullscreen mode

6. Application Properties

Configure application.properties file:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
Enter fullscreen mode Exit fullscreen mode

7. Running the Application

Run the Spring Boot application and access the Swagger UI at:


Conclusion

This guide provided a step-by-step approach to building a Spring Boot CRUD API and integrating Swagger for API documentation. With this setup, you can create scalable REST APIs with self-generated documentation for better maintainability and developer experience.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .