I am creating an API to simulate a vending machine and I'm using Spring, JPA and MySQL. I have an endpoint for a POST request that allows for new user creation by entering the user's details into a table called users
. I have a check to see if the username already exists in the table and if it does, I want to return a message that says the creation of a new user was unsuccessful because that username is already in use. If the user name is not in the table, I want to return the User
object.
How do I return this error message? From what I have found so far, suggestions include the usage of ResponseEntity or creating a custom exception handler which all seemed overly complicated for something that I feel is quite straightforward. Is there an easier way to do this?
So this is what I want the response to look like when a new user has been created successfully (which I have currently managed to get working successfully):
{
"username": "user",
"password": "password",
"role": "BUYER",
"deposit": 0.0,
"id": 12
}
And if it fails, I want it to return something that looks along the lines of:
Error: username already in use.
or:
{
"error" : "Username already in use"
}
User object:
@Entity
@Table(name = "users")
public class User
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int userId;
@NotNull
@Column(name = "username", unique = true)
private String username;
@NotNull
@Column(name = "password")
private String password;
@NotNull
@Column(name = "role")
private Role role;
@NotNull
@Column(name = "deposit")
private BigDecimal deposit;
public User() {}
public User(String username, String password, Role role, BigDecimal deposit)
{
this.username = username;
this.password = password;
this.role = role;
this.deposit = deposit;
}
public int getId()
{
return userId;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public Role getRole()
{
return role;
}
public void setRole(String role)
{
this.role = Role.valueOf(role);
}
public void setRole(Role role) {
this.role = role;
}
public BigDecimal getDeposit()
{
return deposit;
}
public void setDeposit(BigDecimal deposit)
{
this.deposit = deposit;
}
}
Method in the controller that is being called:
@PostMapping(value = "/create-user", consumes = {"application/json"})
public User createUser(@RequestBody User user)
{
return userService.createUser(user);
}
createUser method in UserService:
public User createUser(User user)
{
// if(userRepository.userExists(user.getUsername()) == 0)
return userRepository.save(user);
}
UserRepository
is an interface that extends JpaRepository
.
If I have missed some information or have worded the question incorrectly, please let me know and I'll update accordingly.
CodePudding user response:
This can be achieved in multiple ways.
- You can use JpaRepository's
existsById()
or similar "exists" methods. This would return a boolean. If it's true, that is if the entry already exists for a given id, you can send an error response. Otherwise, new user object. For that, you can have a model class something likeUserOrError
which will either hold a user object or an error string at a time. Use@JsonView
annotation from Jackson library to show/ hide the fields. Read more - Based on the result of the above "exists" method, wrap it with
ResponseEntity<T>
. The return type of your controller method should beResponseEntity<T>
. Here's the link. The advantage of this method is that you can send different HTTP status codes - Throw a custom
RuntimeException
in your service layer and use Spring's exception handling like theRestControllerAdvice
annotation