So far I have done one (REST) project using Spring Boot and liked it a lot. The one thing I found to be somewhat devious was my understanding of @RequestBody
.
Suppose I have the POST method below to login a user. My user entity may contain attributes other than just the username and password I'd like the post-request to have. In this case I saw no other option but to make an extra object (LoginRequest) to hold the data for the incoming data.
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<User> login(@RequestBody LoginRequest request) {
User p = null;
if (request != null) {
p = User.login(request.getEmail(), request.getPassword()); // validates and returns user if exists
if (p != null){
return new ResponseEntity<User>(p, HttpStatus.OK);
}
}
throw new IllegalArgumentException("Password or email incorrect");
}
Similarly, I'd like the @ResponseBody
to return a minimized version of the User object where for example the password is excluded.
What are some of the standard approaches to this issue? Do I really have to make a separate object for every 'json-view'? I did some REST stuff in python before and here I would just have a Dictionary containing the request attributes. Any similar approaches?
Create a new entity if you will persist or operate on it
If you need a custom view for existing entity (add/remove fields) DTO with custom serialization can be used
There maybe a case when you don't want to create DTO because you will not reuse it anywhere, but need some quick solution for custom response you can use Map<String, Object> - the key will be used for JSON field name, and Object is for the value, for example:
@RequestMapping(method = RequestMethod.POST) public Map<String, Object> login(@RequestParam Integer p1) { Map<String, Object> map = new HashMap<>(); map.put("p1", p1); map.put("somethingElse", "456"); return map; }
JSON response:
{
"p1": p1value,
"somethingElse": "456"
}
3rd case will suite you if you're not building too complex bodies with nested objects which should be customized based on some conditions. Use 2nd option in the opposite case.
There are two approaches to this, for both Request and Response -
1. Use Same entities with extra params and populate only what you need. You can check for nulls.
2. Use separate Data Transfer Objects (DTOs) - These basically can be used when entities have different fields than the object you need to transfer.
Personally, I like the first approach to save the effort of mapping entities to DTOs and back. But, sometimes when DTOs need to be totally different, we need to use the second approach. Eg. APIs for dashboards numbers and reports.
HTH
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With