Skip to content

Support limited subset of RFC 6570 syntax including operators "", "?", "/", "#" [SPR-14134] #18706

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

Open
spring-projects-issues opened this issue Apr 8, 2016 · 4 comments
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Apr 8, 2016

Stefan Kühnel opened SPR-14134 and commented

org.springframework.web.util.UriTemplate and org.springframework.web.util.DefaultUriTemplateHandler (and RestTemplate as consequence) don't support the complete syntax of RfC 6570, but Spring HATEOAS has a version that does org.springframework.hateoas.UriTemplate. So the features should be merged into the "standard" template functionality.


Affects: 4.2.5

Issue Links:

1 votes, 2 watchers

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

We've already looked into supporting RFC 6570. It's very extensive and arguably well beyond most needs. Even the spec recognizes that and defines itself in terms of 4 levels (section 1.2). Moreover there are significant differences in the way Spring's URI template support works and we've made a conscious decision not to change the mechanisms in place but rather evolve them as needed, i.e. not seeking compliance with the spec. You can see more comments on that.

Note that the RestTemplate does have a UriTemplateHandler extension point which allows you to completely replace the URI template handling for example swapping out our URI template support with another from an external library that supports RFC 6570.

That said we can consider specific features and enhancements around Spring's URI template handling. That would mean a separate ticket with a more specific request for enhancement.

@spring-projects-issues
Copy link
Collaborator Author

Stefan Kühnel commented

Hello @Rossen Stoyanchev,

thanks for the update and the links.

In the REST scenario we have we had a ressource like Customer. The URI design looks like the following (using RFC 6570 syntax), which follows common best practices from all I can tell:

https://{host}:{port}/v42/customers{/id}{?size,page,name}}

This is very similar to what Spring Data Rest does (e.g. https://spring.io/guides/gs/accessing-data-rest/), but we want some more control.

For a client side wrapper of the ressource, it could look something like the following:

public class Customers
{
    private String ID_PARAM = "id";
    private String SIZE_PARAM = "size";
    private String PAGE_PARAM = "page";
    private String NAME_PARAM = "name";

    // One can easily see and understand the whole structure and design of the resouce URIs with this one line.
    private String URI_TEMPLATE = "https://api.example.com/v42/customers{/id}{?size,page,name}}";

    private RestTemplate template = new RestTemplate();

    public List<Customer> getCustomers(int page, int size)
    {
        Map<String,Object> urlVariables = new HashMap<>();
        urlVariables.add(PAGE_PARAM, page);
        urlVariables.add(SIZE_PARAM, size);
 
	Customer[] customers = template.getForObject(URI_TEMPLATE, Customer[].class, urlVariables);

        return Arrays.asList(customers);
    }

    public Customer getCustomer(long id)
    {
        Map<String,Object> urlVariables = new HashMap<>();
        urlVariables.add(ID_PARAM, id);
 
	Customer customer = template.getForObject(URI_TEMPLATE, Customer.class, urlVariables);

        return customer;
    }

    public List<Customer> searchCustomer(String name)
    {
        Map<String,Object> urlVariables = new HashMap<>();
        urlVariables.add(NAME_PARAM, name);
 
	Customer[] customers = template.getForObject(URI_TEMPLATE, Customer[].class, urlVariables);

        return Arrays.asList(customers);
    }
}

This looks very simple to me: Always the same URI template. The correct URI would be created "automagically" depending on the given urlVariables.

For this to work the types as used in UriTemplate of Spring HATEOAS ("", "?", "/", "#") are sufficient IMHO.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

We can consider an alternative UriTemplateHandler that supports a limited subset of the RFC based on the given list of operators. Probably taking a similar approach as in the Spring HATEOAS UriTemplate, resolving what variables should be added from expressions and then building the URI with UriComponentsBuilder. The main difference is that it would be packaged as a UriTemplateHandler and available to plug into the RestTemplate.

@spring-projects-issues
Copy link
Collaborator Author

Stefan Kühnel commented

Thanks, Rossen, this sounds very good to me. :-)

@spring-projects-issues spring-projects-issues added type: enhancement A general enhancement in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 5.x Backlog milestone Jan 11, 2019
@bclozel bclozel self-assigned this Apr 7, 2020
@bclozel bclozel removed their assignment Sep 22, 2020
@jhoeller jhoeller modified the milestones: 6.x Backlog, General Backlog Oct 1, 2024
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) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants