spring-projects / spring-hateoas

Spring HATEOAS - Library to support implementing representations for hyper-text driven REST web services.
https://spring.io/projects/spring-hateoas
Apache License 2.0
1.04k stars 477 forks source link

Unable to expand() template link #169 #543

Open mdomasevicius opened 7 years ago

mdomasevicius commented 7 years ago

Given

ControllerLinkBuilderFactory linkBuilderFactory = new ControllerLinkBuilderFactory();
linkBuilderFactory.setUriComponentsContributors(singletonList(new HateoasPageableHandlerMethodArgumentResolver()));
@GetMapping("/deals")
    CollectionResource<DealResource> findDeals(
        @RequestParam(required = false) String title,
        @RequestParam(value = "category_id", required = false) Long categoryId,
        @RequestParam(value = "tags[]", required = false) String[] tags,
        @PageableDefault(sort = "position", direction = ASC) Pageable pageable)

When:

Link next = linkBuilderFactory.linkTo(methodOn(MobileVoucherDealsController.class)
                .findDeals(title, categoryId, tags, pageable.next())).withRel("next");

Then: Link: http://localhost:8080/deals?page=1&size=1&sort=position,asc{&title,category_id,tags[]}

When: From #535

Just expand the Link without handing any parameters into the method and you should get a plain URI in turn.

next.expand(TemplateVariables.NONE);

Then:

Illegal character in query at index 59: http://localhost:8080/deals?page=1&size=1&sort=position,asc{&title,category_id,tags[]}


I tried expanding links in the same manner like http://localhost:8080/deals{/id} and it works resulting in http://localhost:8080/deals but not with template being after URL request params

odrotbohm commented 7 years ago

What's the reason you use tags[] as the variable name? We use the declared name in the template and according to the URI template spec, square brackets are not allowed in variable names. That's why the template fails to detect the placeholders in general and then the expansion fails.

mdomasevicius commented 7 years ago

Some iOS libraries:

When sending HTTP requests automatically serialize an array of params in this case tags to tags[]. Since we did not find any guidelines for REST about conventions regarding such case, decided and agreed with API consumers to leave it like this reasoning it would improve readability.