Skip to content

[BUG][C++][cpp-restsdk] cpp-restsdk not able to handle maps with nested schemas ("additionalProperties") #12737

@balintkissdev

Description

@balintkissdev

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?
Description

I would like to use additionalProperties in the OpenAPI definition in order to allow accepting responses in the following JSON payload format (Array of maps with string as map key and a fixed typed object as map value. It would make my job easier if it wouldn't be in an array format, but I have to work with this type definition in a company environment. Namings are already altered to avoid sensitive info.):

[
  {
    "key property 1": {
      "id": 1,
      "name": "value 1"
    },
    "key property 2": {
      "id": 2,
      "name": "value 2"
    },
    "key property 3": {
      "id": 3,
      "name": "value 3"
    }
  }
]

image

In a generated Go client, the return type results in the following, which is the expected in Go:

// api_example.go
[]map[string]NestedSchema

However, I have to write a C++ client, and cpprest-sdk generator on the other hand generates the following type in the function signature:

// api/ExampleApi.h
pplx::task<std::vector<std::shared_ptr<std::map>>> getMapWithNestedSchema() const;

The generated ExampleApi.h and ExampleApi.cpp files do not compile, because std::map lacks the template parameters for the key and value type. Expected output is the following:

// api/ExampleApi.h
pplx::task<std::vector<std::shared_ptr<std::map<utility::string_t, std::shared_ptr<NestedSchema>>>>> getMapWithNestedSchema() const;
openapi-generator version

v6.0.0

OpenAPI declaration file content or url
swagger: '2.0'
info:
  title: Example to reproduce API generation with complex map type
  version: 0.0.0
basePath: /api/v1

schemes:
  - http
consumes:
  - application/json
produces:
  - application/json

tags:
  - name: example

paths:
  '/mapWithNestedSchema':
    get:
      operationId: 'GetMapWithNestedSchema'
      tags:
        - example
      responses:
        200:
          description: OK
          schema:
            type: 'array'
            items:
              $ref: '#/definitions/MapWithNestedSchema'
        500:
          description: Error

definitions:
  MapWithNestedSchema:
    type: 'object'
    description: 'A map with arbitrary string as key and object as value'
    additionalProperties: 
      $ref: '#/definitions/NestedSchema'
    example:
      'key property 1':
        id: 1
        name: 'value 1'
      'key property 2':
        id: 2
        name: 'value 2'
      'key property 3':
        id: 3
        name: 'value 3'
  
  NestedSchema:
    type: 'object'
    properties: 
      id:
        type: 'number'
        example: 1
      name:
        type: 'string'
        example: 'value 1'
Generation Details

generatorName: cpp-restsdk
outputDir: myclient
inputSpec: swagger.yaml

Steps to reproduce
  1. Run v6.0.0 version of openapi-codegen-cli with swagger.yml in the root folder. I used the dockerized execution.
docker run --rm -v "${PWD}:/local" --user "$(shell id -u):$(shell id -g)" openapitools/openapi-generator-cli:v6.0.0 generate \
    -i /local/swagger.yml \
    -g cpp-restsdk \
    -o /local/myclient

Also tried openapitools/openapi-generator-cli:latest too, but result was the same. Tried manually building from master with ./mvnw clean install, but the 6.0.1-SNAPSHOT build failed.

cd myclient
mkdir build
cd build
cmake ..
make
Related issues/PRs

#5148
#5222

Suggest a fix

As a workaround, I currently preprocess my swagger.yml file with sed to change the path to return "typeless items" and use them in code that way.

paths:
  '/mapWithNestedSchema':
    get:
      operationId: 'GetMapWithNestedSchema'
      tags:
        - example
      responses:
        200:
          description: OK
          schema:
            type: 'array'
            items:
              {}   # sed -i 's/$ref: '\''#\/definitions\/MapWithNestedSchema'\''/{}/g' swagger.yml 
        500:
          description: Error
// api/ExampleApi.h
pplx::task<std::vector<std::shared_ptr<Object>>> getMapWithNestedSchema() const;

swagger-codegen-cli:2.4.27 is already able to recognize an array of MapWithNestedSchema types, but has other troubles of generating MapWithNestedSchema as an std::map.

// api/ExampleApi.h
pplx::task<std::vector<std::shared_ptr<MapWithNestedSchema>>> getMapWithNestedSchema();
// models/MapWithNestedSchema.h
class  MapWithNestedSchema
    : public null<String, NestedSchema>
{
  ...
}

I tried copying the existing .mustache file templates for the API header and source and modifying them as a workaround, but so far I was only able to use the {#isMap} directive on request parameter types ({#allParams} -> {dataType}). If there would be a way to specify my custom .mustache file to check for map type or nested type in the result, that would be helpful. On the other hand, I would also appreciate help on how to improve the existing .yml file.

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