Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add controller mapping relative UriComponentsBuilder [SPR-16910] #21449

Closed
spring-projects-issues opened this issue Jun 6, 2018 · 3 comments
Closed
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Jun 6, 2018

Michael Osipov opened SPR-16910 and commented

Consider the following snippet:

 

import java.io.InputStream;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

@RestController
@RequestMapping("/rest/documents")
public class DocumentsController {

	@PostMapping(consumes = "application/zip")
	public ResponseEntity<?> createDocument(InputStream is, UriComponentsBuilder uriBuilder) {

		UriComponents uc = uriBuilder.path("/rest/documents/{id}").buildAndExpand("6667f88a-5783-11e8-857e-001f29e7988e");

		return ResponseEntity.created(uc.toUri()).build();
	}

}

Unfortunately, I have to duplicate /rest/documents with the UriComponentsBuilder. It'd be nice if this components could be controller mapping relative. I'd like to do uriBuilder.path("/{id}").buildAndExpand("6667f88a-5783-11e8-857e-001f29e7988e") only.


Affects: 5.0.6

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

How would the framework know if the injected builder should be application or controller relative? Both are legitimate choices depending on what you're trying to do.

Isn't this what you want?

 

MvcUriComponentsBuilder.fromController(getClass()).path(..).buildAndExpand(".."); 

 

 

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Jun 7, 2018

Michael Osipov commented

While this works for me:

UriComponents uc = MvcUriComponentsBuilder.fromController(uriBuilder, getClass())
    .path("/{id}").buildAndExpand(DEFAULT_ID);

It looks longer than the previous snippet. I'd expect to have MvcUriComponentsBuilder injectable via method arguments to do uriBuilder.path("/{id}").buildAndExpand(DEFAULT_ID) only.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Why the two-arg fromController? The main use case for that is building links outside of the context of a request (e.g. batch application building links off-line).

I agree that MvcUriComponentsBuilder is longer still but it could be wrapped as below, or some such helper method, and on the plus side, one less controller method arg:

private UriComponentsBuilder self() {
    MvcUriComponentsBuilder.fromController(getClass());
}

Or you could make it static and have it anywhere:

private static UriComponentsBuilder documentsController() {
    MvcUriComponentsBuilder.fromController(DocumentsController.class);
}

Or with a static import it becomes fromController(getClass()).

I'm not opposed to some improvement, and it would be a trivial change. I just can't see any obvious ways for a controller to express what it wants. The existing behavior is for the injected builder to be application relative which makes sense since building links to any other controller is probably more common than to the same controller. How would one then switch? A marker interface such as a sub-interface of UriBuilder, or a sub-class or UriComponentsBuilder, or an extra method parameter annotation to express "controller relative" all feel are a bit much for the problem. Instead a private helper method seems fitting for what is a controller-relative mechanism.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants