Skip to content

[BUG] ApiClient fails to encode query paramaters #22339

@Albertwaninge-2

Description

@Albertwaninge-2

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

I ran into an issue with a generated client, which sends an offsetdatetime parameter which contains a + character, e.g. at=2025-11-12T11:00:00+01:00. The server (Tomcat, which is the default server in any Spring Boot project.) interprets the + character as a encoded space and, hence, decodes it to a space. Subsequently, the server tries to parse an OffsetDateTime from "2025-11-12T11:00:00 01:00", which throws a parse exception because it is invalid.

The generated ApiClient in the Kotlin generator with the jvm-spring-restclient template does not encode query params as it should. This is not only problematic for the somewhat ambiguous + character. Also the &, = and ? characters will definitely cause problems.

openapi-generator version

7.15.0 using the kotlin generator and the jvm-spring-restclient library.

Steps to reproduce

Generate a client for an API which has an endpoint which takes a parameter of type string($date-time) (in Java that would be ZonedDateTime, OffsetDateTime or Instant).
The service exposing the API must be hosted on Tomcat server (Spring Boot will do) or any other server that inteprets a + as en encoded space.
Use this client to call that endpoint with a datetime value for a timezone east of GMT (i.e. the offset should have a + character).
Now, the server will throw a parse exception, as it tries to parse a datetime string containing a space rather than a +.

Related issues/PRs

I did not find any related issues.

Suggest a fix

I am no expert on Spring Boots RestClient nor URI or URL encoding. But Spring Boots manual has a nice page on URI encoding: https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-uri-building.html#uri-encoding

Based on that manual, I guess the solution would be something of the following:

Replace the function in the generated ApiClient

private fun <I> RestClient.RequestBodyUriSpec.uri(requestConfig: RequestConfig<I>) =
        uri(requestConfig.path) { builder ->
            builder
                .queryParams(LinkedMultiValueMap(requestConfig.query))
                .build(requestConfig.params)
        }

with something like

private fun <I> RestClient.RequestBodyUriSpec.uri(requestConfig: RequestConfig<I>): RestClient.RequestBodySpec {
        val uriComponentsBuilder  = UriComponentsBuilder.fromPath(requestConfig.path)
        requestConfig.query.forEach { key, values ->
            uriComponentsBuilder.queryParam(key, "{$key}")
        }
        return uri(uriComponentsBuilder.encode().buildAndExpand(requestConfig.query + requestConfig.params).toUri())
    }

I have tried the above solution for myself and it worked. But I did not exhaustively test for exotic sets of params. And I wonder whether this functions properly when parameters have collections.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions