ferdikoomen / openapi-typescript-codegen

NodeJS library that generates Typescript or Javascript clients based on the OpenAPI specification
MIT License
2.92k stars 519 forks source link

Is there a example of multipart/form-data request? #1000

Open dim0627 opened 2 years ago

dim0627 commented 2 years ago

Thanks for so awesome library! I'm using openapi-typescript-codegen so many projects.

I have in trouble. I wanna use in React Native project for image file upload usecase with expo-image-picker. But I couldn't implements this with FormData pattern and Blob pattern. Is there an example of multipart/form-data request?

snap608 commented 2 years ago

Hi,

I had the same issue. Using this in a React Native project and POSTing with FormData.

There is a bug in the codegen tool.

I have managed to get this to work in the end.

  1. Issue with default export in request.js

    const getFormData = (options) => {
    if (options.formData) {
        //const formData = new form_data_1.default(); // <-- Had to change this
        const formData = new form_data_1(); // <-- To this
        return formData;
    }
    return undefined;
    };
  2. Issue with request.js in getHeaders()

This test do not check options.formData if it is set so the request do not have any data.

...
    if (options.body) {
        if (options.mediaType) {
            headers['Content-Type'] = options.mediaType;
        }
        else if (isBlob(options.body)) {
            headers['Content-Type'] = options.body.type || 'application/octet-stream';
        }
        else if (isString(options.body)) {
            headers['Content-Type'] = 'text/plain';
        }
        else if (!isFormData(options.body)) {
            headers['Content-Type'] = 'application/json';
        }
    }
...

This is due to the generated code:

    static postUpload(formData) {
        return (0, request_1.request)(OpenAPI_1.OpenAPI, {
            method: 'POST',
            url: '/Upload',
            formData: formData, // <-- Will not work due to the test above
            mediaType: 'multipart/form-data'
        });

A workaround here is to do this by setting the body:

    static postUpload(formData) {
        return (0, request_1.request)(OpenAPI_1.OpenAPI, {
            method: 'POST',
            url: '/Upload',
            body: formData, // <-- Passing as body due to the test described above
            mediaType: 'multipart/form-data'
        });

PS: If you use the body insted of formData the issue in pt. 1 will also never happen.

I hope this help both you and the devs. :)

JSH32 commented 2 years ago

Yep, this happens to me too, hope a fix can be merged soon

acherkashin commented 1 year ago

It happens to me too.

@ferdikoomen Do we have any plans to fix it?

acherkashin commented 1 year ago

Everything works fine if I remove "default()"

Screenshot 2022-12-27 at 08 44 18

my open api schema looks in the following way:

/albums:
    post:
      operationId: getAlbums
      tags:
        - "albums"
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                "album-ids":
                  type: string
                  example: "18837614,23899279,23754447,21808509,23529901,22231572,10935745,23342620,23190604,23240656"
      security:
        - oAuth: []
        - oAuthProxied: []
      responses:
        200:
          description: Ok
          content:
            application/json:
acherkashin commented 1 year ago

It happens due to typings issue in form-data package. Here is the issue.

To fix it, need to replace

import FormData from 'form-data'

with

import * as FormData from 'form-data'

As a workaround, you can copy request.ts, make this change and use this modified file as a custom request file. You can find instruction here.