helidon-io / helidon

Java libraries for writing microservices
https://helidon.io
Apache License 2.0
3.44k stars 562 forks source link

UriQueryWriteable.fromQueryString does not support multi-value parameters #8886

Closed romain-grecourt closed 2 weeks ago

romain-grecourt commented 2 weeks ago

Environment Details


Problem Description

When using a client to make a request with multi-value query params, only the last value is retained.

Steps to reproduce

@Test
void testMultiValueQueryParam() {
    try (Http1ClientResponse response = client.get("/greet")
            .queryParam("foo", "bar1")
            .queryParam("foo", "bar2")
            .request()) {

        assertThat(response.lastEndpointUri().query().all("foo"), is(List.of("bar1", "bar2")));
        // fails because we get ["bar2"]
    }
}

It boils down to UriQueryWriteable.fromQueryString:

@Test
void testFromQueryWithMultiValueParameter() {
    UriQueryWriteable uriQuery = UriQueryWriteable.create();
    uriQuery.fromQueryString("foo=bar1&foo=bar2");
    assertThat(uriQuery.all("foo"), is(List.of("bar1", "bar2"))); 
    // fails because we get ["bar2"]
}
tomas-langer commented 2 weeks ago

The first example is expected to work this way - the signature is queryParam(String name, String... values) So you should do: queryParam("foo", "bar1", "bar2")

tomas-langer commented 2 weeks ago

The second example is showing a bug in our code.

tomas-langer commented 2 weeks ago

The method io.helidon.common.uri.UriQueryWriteableImpl#addRaw should call add instead of set for each value