Open In App

How to Add @RestController to Spring WebFlux Applications?

Spring WebFlux is fully non-blocking and supports reactive streamback pressure. It works well with non-blocking servers like Netty and Undertow. The reactive model allows handling more connections with fewer threads. It provides reactive support at multiple levels: Web layer, security, WebClient, template engines, etc. Many Spring components have been updated to work reactively. It can run on both event loop and thread pool backends. This provides flexibility to tune the concurrency model to the workload.

It supports two programming models:



Note: Spring WebFlux is a reactive web framework introduced in Spring Framework 5.0.

@RestController in Spring WebFlux

Advantages of using @RestController in Spring WebFlux

Implementation of @RestController in Spring Webflux Application

Below are the steps to implement @RestController to Spring Webflux applications.



Step 1: Create a new Spring MVC Project




<?xml version="1.0" encoding="UTF-8"?> 
    <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.example</groupId
    <artifactId>REST_Spring_Flux</artifactId
    <version>0.0.1-SNAPSHOT</version
    <name>REST_Spring_Flux</name
    <description>Demo project for Spring Boot</description
    <properties
        <java.version>17</java.version
    </properties
    <dependencies
        <dependency
            <groupId>org.springframework.boot</groupId
            <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId
        </dependency
        <dependency
            <groupId>org.springframework.boot</groupId
            <artifactId>spring-boot-starter-webflux</artifactId
        </dependency
        <dependency
            <groupId>org.projectlombok</groupId
            <artifactId>lombok</artifactId
            <optional>true</optional
        </dependency
        <dependency
            <groupId>org.springframework.boot</groupId
            <artifactId>spring-boot-starter-test</artifactId
            <scope>test</scope
        </dependency
        <dependency
            <groupId>io.projectreactor</groupId
            <artifactId>reactor-test</artifactId
            <scope>test</scope
        </dependency
    </dependencies
    <build
        <plugins
            <plugin
                <groupId>org.springframework.boot</groupId
                <artifactId>spring-boot-maven-plugin</artifactId
                <configuration
                    <excludes
                        <exclude
                            <groupId>org.projectlombok</groupId
                            <artifactId>lombok</artifactId
                        </exclude
                    </excludes
                </configuration
            </plugin
        </plugins
    </build
</project>

Project Structure:

Step 2: Configure MongoDB Database

# MongoDB properties
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=student_management

Step 3: Create Model Class

Student.java:




package com.example.demo.entities;
  
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
  
/**
 * Entity representing a student.
 */
@Document
public class Student 
{
    @Id
    private String id;
    private String name;
    private int age;
    // Constructor
    public Student(String id, String name, int age) 
    {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
    }
      
    public Student() {
        super();
    }
    // Getters and Setters
    public String getId() {
        return id;
    }
  
    public void setId(String id) {
        this.id = id;
    }
  
    public String getName() {
        return name;
    }
  
    public void setName(String name) {
        this.name = name;
    }
  
    public int getAge() {
        return age;
    }
  
    public void setAge(int age) {
        this.age = age;
    }
}

Step 4: Create Repository Interface




package com.example.demo.repositories;
  
import com.example.demo.entities.Student;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
  
/**
 * Repository interface for managing student entities.
 */
public interface StudentRepository extends ReactiveMongoRepository<Student, String> {
}

Step 5: Create Controller Class




package com.example.demo.controller;
  
import com.example.demo.entities.Student;
import com.example.demo.services.StudentService;
import org.springframework.web.bind.annotation.*;
  
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
  
/**
 * Controller for handling student-related API endpoints.
 */
@RestController
@RequestMapping("/api/students")
public class StudentController {
  
    private final StudentService studentService;
  
    public StudentController(StudentService studentService) {
        this.studentService = studentService;
    }
  
    /**
     * Save a student.
     */
    @PostMapping
    public Mono<Student> createStudent(@RequestBody Student student) {
        return studentService.saveStudent(student);
    }
  
    /**
     * Get all students.
     */
    @GetMapping
    public Flux<Student> getAllStudents() {
        return studentService.getAllStudents();
    }
  
    /**
     * Get a student by ID.
     */
    @GetMapping("/{id}")
    public Mono<Student> getStudentById(@PathVariable String id) {
        return studentService.getStudentById(id);
    }
  
    /**
     * Delete a student by ID.
     */
    @DeleteMapping("/{id}")
    public Mono<Void> deleteStudent(@PathVariable String id) {
        return studentService.deleteStudent(id);
    }
}

Step 6: Create Service Interface




package com.example.demo.services;
  
import com.example.demo.entities.Student;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
  
/**
 * Interface defining methods for managing Student entities
 */
public interface StudentService {
  
    /**
     * Saves a student.
     */
    Mono<Student> saveStudent(Student student);
  
    /**
     * Get all students
     */
    Flux<Student> getAllStudents();
  
    /**
     * Get a student by the ID
     */
    Mono<Student> getStudentById(String id);
  
    /**
     * Deletes a student by its ID
     */
    Mono<Void> deleteStudent(String id);
}

Step 7: Create Service Implementation




package com.example.demo.services;
  
import com.example.demo.entities.*;
import com.example.demo.repositories.StudentRepository;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
  
/**
 * Service layer implementation for handling Student entities.
 */
@Service
public class StudentServiceImpl implements StudentService {
  
    private final StudentRepository studentRepository;
  
    public StudentServiceImpl(StudentRepository studentRepository) {
        this.studentRepository = studentRepository;
    }
  
    /**
     * Save a student.
     */
    @Override
    public Mono<Student> saveStudent(Student student) {
        return studentRepository.save(student);
    }
  
    /**
     * Get all students.
     */
    @Override
    public Flux<Student> getAllStudents() {
        return studentRepository.findAll();
    }
  
    /**
     * Get a student by ID.
     */
    @Override
    public Mono<Student> getStudentById(String id) {
        return studentRepository.findById(id);
    }
  
    /**
     * Delete a student by ID.
     */
    @Override
    public Mono<Void> deleteStudent(String id) {
        return studentRepository.deleteById(id);
    }
}

Step 8: Run the Application

Now, we can run the Spring Boot application from IDE or by using the command-line tool.

mvn spring-boot:run

Step 9: Test the Endpoints Using Postman

POST: http://localhost:8080/api/students-- Post the student data
GET: http://localhost:8080/api/students-- Get all student details
GET: http://localhost:8080/api/students/{id} -- Get the student details by Id

Output:

We can refer the following Output Video to see the execution of the application, database, endpoint testing using POSTMAN.


Article Tags :