Manweill / swagger-axios-codegen

swagger client to use axios and typescript
MIT License
306 stars 83 forks source link

Support derived types in request body #110

Closed Ultre00 closed 2 years ago

Ultre00 commented 4 years ago

When I use the following json:

"/api/app/customer": {
      "post": {
        "tags": [
          "Customer"
        ],
        "operationId": "CreateAsync",
        "requestBody": {
          "content": {
            "application/json-patch+json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/CreateUpdateCompanyDto"
                  },
                  {
                    "$ref": "#/components/schemas/CreateUpdateContactDto"
                  }
                ],
                "nullable": true
              }
            },
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/CreateUpdateCompanyDto"
                  },
                  {
                    "$ref": "#/components/schemas/CreateUpdateContactDto"
                  }
                ],
                "nullable": true
              }
            },
            "text/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/CreateUpdateCompanyDto"
                  },
                  {
                    "$ref": "#/components/schemas/CreateUpdateContactDto"
                  }
                ],
                "nullable": true
              }
            },
            "application/*+json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/CreateUpdateCompanyDto"
                  },
                  {
                    "$ref": "#/components/schemas/CreateUpdateContactDto"
                  }
                ],
                "nullable": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerDto"
                }
              }
            }
          }
        }
      },

The generated code has an empty request body:

static createAsync(options: IRequestOptions = {}): Promise<CustomerDto> {
    return new Promise((resolve, reject) => {
      let url = '/api/app/customer';

      const configs: IRequestConfig = getConfigs('post', 'application/json', url, options);

      let data = null;

      configs.data = data;
      axios(configs, resolve, reject);
    });
  }

Is it possible to add support for derived types, or is it already supported and I am missing something here ?

Manweill commented 4 years ago

@arkraft Can you help solve this problem

arkraft commented 4 years ago

@Manweill Yes sure, i can take a look at it. But i won't be able to do so till Monday. @Ultre00 Does this work with other codegenerators? Could you test it on https://editor.swagger.io/ with the typescript-angular for example. It would help to see how the result of that looks like.

Ultre00 commented 4 years ago

@arkraft It does work with other generators. I tested with the typescript-angular you mentioned aswell and that does also work. The code generated:

public createAsync(body?: Body1, observe?: 'body', reportProgress?: boolean): Observable<CustomerDto>;
    public createAsync(body?: Body1, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<CustomerDto>>;
    public createAsync(body?: Body1, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<CustomerDto>>;
    public createAsync(body?: Body1, observe: any = 'body', reportProgress: boolean = false ): Observable<any> {

        let headers = this.defaultHeaders;

        // to determine the Accept header
        let httpHeaderAccepts: string[] = [
            'text/plain',
            'application/json',
            'text/json'
        ];
        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
        if (httpHeaderAcceptSelected != undefined) {
            headers = headers.set('Accept', httpHeaderAcceptSelected);
        }

        // to determine the Content-Type header
        const consumes: string[] = [
            'application/json-patch+json',
            'application/json',
            'text/json',
            'application/_*+json'
        ];
        const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
        if (httpContentTypeSelected != undefined) {
            headers = headers.set('Content-Type', httpContentTypeSelected);
        }

        return this.httpClient.request<CustomerDto>('post',`${this.basePath}/api/app/customer`,
            {
                body: body,
                withCredentials: this.configuration.withCredentials,
                headers: headers,
                observe: observe,
                reportProgress: reportProgress
            }
        );
    }

Not sure why it's called Body1. However the generated code looks fine aswell:

import { CreateUpdateCompanyDto } from './createUpdateCompanyDto';
import { CreateUpdateContactDto } from './createUpdateContactDto';

export type Body1 = CreateUpdateCompanyDto | CreateUpdateContactDto;