OpenAPITools / OpenAPITools/openapi-generator

[BUG][Java][resttemplate][webclient] Error sending Accept header

Open
#19,493 2 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • 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 have an operation that defines two Accept headers: application/json and application/xml.

openapi: 3.0.0
info:
  description: >-
    This spec is mainly for testing Petstore server and contains fake endpoints,
    models. Please do not use this for any other purpose. Special characters: ’
    \
  version: 1.0.0
  title: OpenAPI Petstore
  license:
    name: Apache-2.0
    url: ‘https://www.apache.org/licenses/LICENSE-2.0.html’

paths:
  ‘/myapi’:
    get:
      operationId: my api
      summary: my api
      tags:
        - 'Invoice'
      responses:
        ‘200’:
          description: ‘My return’
          content:
            application/xml:
              schema:
                type: string
            application/json:
              schema:
                type: string

I try to send the Accept header with application/xml value but it is always sent with application/json value.
I tried adding a defaultHeader to the header but in that case it sends {application/json,application/xml} (in that order) so it is also incorrect.

    @Bean
    public InvoiceApi invoiceApiXML(final ApiClient apiClientXML) {
        apiClientXML.addDefaultHeader("Accept", "application/xml");
        return new InvoiceApi(apiClientXML);
    }

    @Bean
    public InvoiceApi invoiceApiJSON(final ApiClient apiClientJSON) {
        apiClientJSON.addDefaultHeader("Accept", "application/json");
        return new InvoiceApi(apiClientJSON);
    }

I think the problem is this method that if application/json is present it always gets this value.

ApiClient.java

    /**
     * Select the Accept header's value from the given accepts array:
     *     if JSON exists in the given array, use it;
     *     otherwise use all of them (joining into a string)
     *
     * @param accepts The accepts array to select from
     * @return List The list of MediaTypes to use for the Accept header
     */
    public List<MediaType> selectHeaderAccept(String[] accepts) {
        if (accepts.length == 0) {
            return null;
        }
        for (String accept : accepts) {
            MediaType mediaType = MediaType.parseMediaType(accept);
            if (isJsonMime(mediaType) && !isProblemJsonMime(accept)) {
                return Collections.singletonList(mediaType);
            }
        }
        return MediaType.parseMediaTypes(StringUtils.arrayToCommaDelimitedString(accepts));
    }

Is that a bug, does it have a reason that escapes me? I don't know the reason for always choosing application/json

openapi-generator version

7.8.0

Generation Details
java -jar openapi-generator-cli-7.8.0.jar generate -g java -i spec.yml -o out --additional-properties library=resttemplate
Steps to reproduce
Related issues/PRs
Suggest a fix

My ideal solution would be to overload the methodIdWithHttpInfo method by adding a new parameter for custom headers.
This way, in case the Accept header is present, it will take precedence over application/json.

Also, this would solve what I consider to be a necessity. To be able to add headers per request.

Sample:

    public ResponseEntity<String> myApiWithHttpInfo(HttpHeaders httpHeaders) throws RestClientException { //overload method myApiWithHttpInfo adding HttpHeaders
        Object localVarPostBody = null;


        final MultiValueMap<String, String> localVarQueryParams = new LinkedMultiValueMap<String, String>();
        final HttpHeaders localVarHeaderParams = new HttpHeaders();
        final MultiValueMap<String, String> localVarCookieParams = new LinkedMultiValueMap<String, String>();
        final MultiValueMap<String, Object> localVarFormParams = new LinkedMultiValueMap<String, Object>();

        final String[] localVarAccepts = {
                "application/xml", "application/json"
        };
        final List<MediaType> localVarAccept = apiClient.selectHeaderAccept(localVarAccepts, httpHeaders); //overload method selectHeaderAccept
        final String[] localVarContentTypes = {  };
        final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);

        String[] localVarAuthNames = new String[] {  };

        localVarHeaderParams.addAll(httpHeaders); //add headers to the request

        ParameterizedTypeReference<String> localReturnType = new ParameterizedTypeReference<String>() {};
        return apiClient.invokeAPI("/myapi", HttpMethod.GET, Collections.<String, Object>emptyMap(), localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType);
    }

Thank you very much

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ApiClient.java and its selectHeaderAccept method, then inspect the generated myApiWithHttpInfo entry point produced by the Java resttemplate command. Reproduce the request from the supplied OpenAPI spec and verify how application/xml, application/json, and custom headers are sent; done means the intended Accept value and per-request behavior are clearly covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.