Reputation: 2194
My Spring Boot
1.4 application has this POST
HTTP Method to create a resource. As a requirement, it should spit a location header specifying the URL of the newly created resource: RFC 9110 HTTP Semantics - Method Definitions. I am just wondering if there is any good way to do it than manually constructing the URL and adding it to the response.
Any helps/clues are deeply appreciated
Upvotes: 22
Views: 26833
Reputation: 4415
@Autowired
private UserService service;
@PostMapping("/users")
public ResponseEntity<Object> createUser(@RequestBody User user)
{
User myUser = service.save(user);
URI location = ServletUriComponentsBuilder
.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(myUser.getId())
.toUri();
ResponseEntity.created(location).build()
}
Upvotes: 3
Reputation: 2510
This answer pointed me in the right direction, but my create entity endpoint path was slightly different from the path where the saved entity was stored.
I was able to use fromCurrentRequest()
and replacePath("new path here")
like so:
URI uri = ServletUriComponentsBuilder.fromCurrentRequest()
.replacePath("/customer/{id}/fat")
.buildAndExpand(savedCustomer.getCustomerId())
.toUri();
return ResponseEntity.created(uri).build();
Upvotes: 1
Reputation: 2296
This exact scenario is demonstrated in the Building REST Services with Spring Guide.
Once you have persisted your new entity, in your controller you can use the below:
URI location = ServletUriComponentsBuilder
.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(newEntity.getId())
.toUri();
You can then add this to your response using ResponseEntity as below:
ResponseEntity.created(location).build()
or
ResponseEntity.status(CREATED).header(HttpHeaders.LOCATION, location).build()
The latter expects a string so you can use toUriString()
on the uri builder instead of toUri()
.
Upvotes: 54
Reputation: 2600
Another way is to use UriComponentsBuilder
. You can inject it right into a controller method:
@PostMapping(consumes = { MediaType.APPLICATION_JSON_UTF8_VALUE })
public ResponseEntity<Void> addCustomer(
UriComponentsBuilder uriComponentsBuilder,
@RequestBody CustomerRequest customerRequest ){
final long customerId = customerService.addCustomer(customerRequest)
UriComponents uriComponents =
uriComponentsBuilder.path("/{id}").buildAndExpand(customerId);
return ResponseEntity.created(uriComponents.toUri()).build();
}
Take note that the following will not compute the current request path. You will need to add it manually (or I might be missing something).
ex:
UriComponents uriComponents =
uriComponentsBuilder.path("CURRENT_REQUEST_PATH/{id}")
.buildAndExpand(customerId);
Upvotes: 5