Skip to content

Support various ways to encode collections in URL parameters for declarative HTTP interfaces #33154

@doljae

Description

@doljae

I've been making good use of the declarative HTTP interface feature that was added in the latest spring release.
I would like HTTP interface to be a bit more versatile and support different encoding methods for @RequestParam.

Currently, the encoding method for @RequestParam of type collection seems to be repeating the same key with &, which seems to be related to the way RequestParamArgumentResolver is implemented.

interface TestRepository {
	@GetExchange("/test")
	Repository test(@RequestParam List<String> param);
}

@Service
@RequiredArgsConstructor
public class TestService {
        private TestRepository repository;

        public void test() {
                List<String> param = List.of("1", "2", "3");
                repository.test(param); // Generated URI path -> GET /test?param=1&param=2&param=3
        }
}

Of course Modern web frameworks expect @RequestParam to be deserialized to collection type automatically, either by repeating the same key value as &, or by parsing strings joined by certain delimiters.
However, if this is not possible due to limitations of older web frameworks or API specs, we have to join the strings with a specific delimiter before the request and then pass the strings as @RequestParam, which is not cool.

It would be nice to have the ability to encode @RequestParam via @CollectionFormat, which is supported by Spring Cloud OpenFeign. I think users who use declarative HTTP interface will have experience with Spring Cloud OpenFeign and will expect a smooth transition.

interface TestRepository {
	@GetExchange("/test1")
	Repository test1(@RequestParam @CollectionFormat(CSV) List<String> param);

	@GetExchange("/test2")
	Repository test2(@RequestParam @CollectionFormat(SSV) List<String> param);
}

@Service
@RequiredArgsConstructor
public class TestService {
        private TestRepository repository;

        public void test() {
                List<String> param = List.of("1", "2", "3");
                repository.test1(param); // Generated URI path -> GET /test1?param=1,2,3
                repository.test2(param); // Generated URI path -> GET /test2?param=1 2 3
        }
}

I'm curious to know what the maintainers think about this 🙂

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)status: supersededAn issue that has been superseded by anothertype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions