I have a Springboot Reactive Web Rest API with a Mongo Database.
My Method in my UserHandler
for adding a user looks like this:
public Mono<User> addUser(Mono<User> user) {
return user
.flatMap(u -> repo.findByEmail(u.getEmail())
.flatMap(existingUser -> Mono.error(
new UserAlreadyExistsException(String.format("User with email '%s' already exists.", existingUser.getEmail())))))
.switchIfEmpty(user.flatMap(repo::insert))
.cast(User.class);
}
The UserController looks like this.
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserHandler userService;
...
@PostMapping
public Mono<User> addUser(@Valid @RequestBody Mono<User> user) {
return userService.addUser(user);
}
...
}
When I now make a post call with postman I get the expected UserAlreadyExists
exception when I try to insert an existing one. But I get this exception when I try to insert a new one:
{
"type": "about:blank",
"title": "Bad Request",
"status": 400,
"detail": "Invalid request content",
"instance": "/users"
}
And the user wont be inserted.
But when I simplify the method to not check, just insert, it works without any errors and the new user will be inserted (same body for the POST).
public Mono<User> addUser(Mono<User> user) {
return user.flatMap(repo::insert);
}
For the sake of completeness, here the body of the request:
{
"firstname": "Alice",
"lastname": "Jones",
"email": "alice.jones@example.com",
"bio": "Lorem ipsum dolor sit amet",
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"zipCode": "12345",
"country": "USA"
},
"phoneNumber": "123-456-7890"
}
The UserRepository Interface:
public interface UserRepository extends ReactiveMongoRepository<User, String> {
Mono<User> findByEmail(String email);
}
And the UserEntity:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "users")
public class User {
@Id
private String id;
@NotBlank
private String firstname;
@NotBlank
private String lastname;
@Indexed(unique = true)
@Email
private String email;
private String bio;
private Address address;
private String phoneNumber;
}
As well as my RestResponseEntityExceptionHandler:
@ControllerAdvice
@ResponseStatus
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorMessage> userNotFoundException(UserNotFoundException exception) {
ErrorMessage message = new ErrorMessage(HttpStatus.NOT_FOUND, exception.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(message);
}
@ExceptionHandler(UserAlreadyExistsException.class)
public ResponseEntity<ErrorMessage> userAlreadyExsistsException(UserAlreadyExistsException exception) {
ErrorMessage message = new ErrorMessage(HttpStatus.BAD_REQUEST, exception.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(message);
}
}
What am I doing wrong?