Skip to content

[typescript-fetch] serialize complex type in multipart/form-data as JSON#7677

Merged
macjohnny merged 1 commit intoOpenAPITools:masterfrom
verokarhu:serialize-complex-types-as-json-in-typescript-fetch
Oct 23, 2020
Merged

[typescript-fetch] serialize complex type in multipart/form-data as JSON#7677
macjohnny merged 1 commit intoOpenAPITools:masterfrom
verokarhu:serialize-complex-types-as-json-in-typescript-fetch

Conversation

@verokarhu
Copy link
Contributor

@verokarhu verokarhu commented Oct 12, 2020

Complex types need to be serialized as JSON to avoid FormData.append()
from converting them into strings through .toString().

Fixes #7658

Tested locally by running the generator against the following schema:

---
openapi: "3.0.0"
info:
  title: Bug test case
  version: "1.0"
paths:
  /example:
    post:
      operationId: exampleOperation
      requestBody:
        content:
          multipart/form-data:
            schema:
              properties:
                simpleValue:
                  type: string
                fileValue:
                  format: binary
                  type: string
                complexvalue:
                  properties:
                    value1:
                      type: number
                    value2:
                      type: string
                  type: object
                complexvalue_with_underscores:
                  properties:
                    value_1:
                      type: string
                    value_2:
                      type: number
                  type: object
              type: object
      responses:
        "201":
          description: Created

This resulted in the following serialization code:

export interface ExampleOperationRequest {
    simpleValue?: string;
    fileValue?: Blob;
    complexvalue?: ExampleComplexvalue;
    complexvalueWithUnderscores?: ExampleComplexvalueWithUnderscores;
}
export interface ExampleComplexvalue {
    /**
     * 
     * @type {number}
     * @memberof ExampleComplexvalue
     */
    value1?: number;
    /**
     * 
     * @type {string}
     * @memberof ExampleComplexvalue
     */
    value2?: string;
}
export function ExampleComplexvalueToJSON(value?: ExampleComplexvalue | null): any {
    if (value === undefined) {
        return undefined;
    }
    if (value === null) {
        return null;
    }
    return {
        
        'value1': value.value1,
        'value2': value.value2,
    };
}
export interface ExampleComplexvalueWithUnderscores {
    /**
     * 
     * @type {string}
     * @memberof ExampleComplexvalueWithUnderscores
     */
    value1?: string;
    /**
     * 
     * @type {number}
     * @memberof ExampleComplexvalueWithUnderscores
     */
    value2?: number;
}
export function ExampleComplexvalueWithUnderscoresToJSON(value?: ExampleComplexvalueWithUnderscores | null): any {
    if (value === undefined) {
        return undefined;
    }
    if (value === null) {
        return null;
    }
    return {
        
        'value_1': value.value1,
        'value_2': value.value2,
    };
}
        if (requestParameters.simpleValue !== undefined) {
            formParams.append('simpleValue', requestParameters.simpleValue as any);
        }

        if (requestParameters.fileValue !== undefined) {
            formParams.append('fileValue', requestParameters.fileValue as any);
        }

        if (requestParameters.complexvalue !== undefined) {
            formParams.append('complexvalue', new Blob([JSON.stringify(ExampleComplexvalueToJSON(requestParameters.complexvalue))], { type: "application/json", }));
        }

        if (requestParameters.complexvalueWithUnderscores !== undefined) {
            formParams.append('complexvalue_with_underscores', new Blob([JSON.stringify(ExampleComplexvalueWithUnderscoresToJSON(requestParameters.complexvalueWithUnderscores))], { type: "application/json", }));
        }

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • If contributing template-only or documentation-only changes which will change sample output, build the project beforehand.
  • Run the shell script ./bin/generate-samples.shto update all Petstore samples related to your fix. This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master. These must match the expectations made by your contribution. You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*. For Windows users, please run the script in Git BASH.
  • File the PR against the correct branch: master
  • Copy the technical committee to review the pull request if your PR is targeting a particular programming language.

@TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) @macjohnny (2018/01) @topce (2018/10) @akehir (2019/07) @petejohansonxo (2019/11) @amakhrov (2020/02)

@auto-labeler
Copy link

auto-labeler bot commented Oct 12, 2020

👍 Thanks for opening this issue!
🏷 I have applied any labels matching special text in your issue.

The team will review the labels and make any necessary changes.

Copy link
Member

@macjohnny macjohnny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for your contribution

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if the parameter is e.g. a Blob, is it also a primitive type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's a primitive. I updated the PR cover letter with test details that includes binary data.

@verokarhu verokarhu requested a review from macjohnny October 13, 2020 07:21
@verokarhu
Copy link
Contributor Author

I may have run into an issue with the fix as-is, I'll convert this into a draft until it's fixed.

@verokarhu verokarhu marked this pull request as draft October 14, 2020 17:19
…SON (#7658)

Complex types need to be serialized as JSON to avoid FormData.append()
from converting them into strings through .toString(). The generated
ToJSON mapper is used in case the value name has underscores or other
unusual characters.

Signed-off-by: Andreas Metsälä <andreas.metsala@gmail.com>
@verokarhu verokarhu marked this pull request as ready for review October 14, 2020 21:31
@verokarhu
Copy link
Contributor Author

I may have run into an issue with the fix as-is, I'll convert this into a draft until it's fixed.

Fixed it, a straightforward conversion did not work with unusual names. The object has to be run through the generated ToJSON mapper method.

@verokarhu
Copy link
Contributor Author

verokarhu commented Oct 23, 2020

Might this be able to make it to the next beta?

Copy link
Member

@macjohnny macjohnny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@macjohnny macjohnny merged commit 490068a into OpenAPITools:master Oct 23, 2020
@macjohnny macjohnny added this to the 5.0.0 milestone Oct 23, 2020
@verokarhu verokarhu deleted the serialize-complex-types-as-json-in-typescript-fetch branch October 23, 2020 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG][typescript-fetch] Complex values are serialized as the string [object Object] in multipart/form-data

2 participants