Building Reactive CRUD APIs with Spring WebFlux and MongoDB
This guide introduces MongoDB fundamentals and demonstrates how to integrate it with Spring WebFlux to create a fully reactive CRUD service, covering dependencies, configuration, entity definitions, repository interfaces, service logic, and controller endpoints.
Environment: Spring Boot 2.5.8
MongoDB Introduction
MongoDB is an open‑source, distributed document database written in C++. It stores data as JSON‑like documents, allowing flexible schemas, automatic sharding for high‑load scalability, and rich query capabilities.
Key Features:
Document‑oriented storage with simple operations.
Index any field to accelerate sorting and queries.
Supports replication and sharding for horizontal scaling.
Rich JSON‑based query language for nested objects and arrays.
Update commands can replace whole documents or modify specific fields.
Map/Reduce for batch processing and aggregation, written in JavaScript.
GridFS for storing large files.
Server‑side JavaScript execution for custom functions.
WebFlux Introduction
Spring WebFlux is a fully non‑blocking, reactive web framework added in Spring 5.0. It runs on Netty, Undertow, or Servlet 3.1+ containers and supports back‑pressure via Reactive Streams, coexisting with Spring MVC.
Dependencies and Configuration
<code><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></code>Configuration (application.yml):
<code>spring:
data:
mongodb:
uri: mongodb://localhost:27017/demo
---
logging:
level:
'[org.springframework.data.mongodb.core]': debug</code>Entity & Repository
<code>@Document(collection = "c_users")
public class Users {
// Primary key maps to MongoDB _id
@Id
private Long id;
private String username;
private String password;
private Integer age;
private String email;
}
public interface UsersRepository extends ReactiveSortingRepository<Users, Long> {
}
</code>Service Class
<code>@Service
public class UsersService {
@Resource
private ReactiveMongoTemplate template;
@Resource
private UsersRepository ur;
// Save a user
public Mono<Users> save(Users user) {
return ur.save(user);
}
// Update user information
public Mono<UpdateResult> updateInfo(Users user) {
return template.updateFirst(
query(where("id").is(user.getId())),
update("email", user.getEmail()).set("username", user.getUsername()),
Users.class);
}
// Delete a user by id
public Mono<Void> remove(Long id) {
return ur.deleteAll(ur.findById(id));
}
// Fuzzy search by username
public Flux<Users> queryUsersLike(String keyword) {
Pattern pattern = Pattern.compile("^.*" + keyword + ".*$");
return template.find(query(where("username").regex(pattern)), Users.class);
}
// Retrieve all users
public Flux<Users> queryUsers() {
return ur.findAll();
}
// Paginated query
public Flux<Users> queryPager(Integer page, Integer size) {
Pageable pageable = PageRequest.of(page, size);
Query query = new Query();
return template.find(query.with(pageable), Users.class);
}
}
</code>Controller Interface
<code>@Resource
private UsersService us;
@PostMapping("save")
public Mono<Users> save(@RequestBody Users users) {
return us.save(users);
}
@PostMapping("update")
public Mono<UpdateResult> update(@RequestBody Users user) {
return us.updateInfo(user);
}
@GetMapping("/remove/{id}")
public Mono<Void> remove(@PathVariable("id") Long id) {
return us.remove(id);
}
@GetMapping("query")
public Flux<Users> query() {
return us.queryUsers();
}
@GetMapping("/queryLike")
public Flux<Users> queryLike(String keyword) {
return us.queryUsersLike(keyword);
}
@GetMapping("/queryPager")
public Flux<Users> queryPager(Integer page, Integer size) {
return us.queryPager(page, size);
}
</code>Repository Supported Query Syntax
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.