samchon / nestia

NestJS Helper Libraries + TypeScript OpenAPI generator
https://nestia.io/
MIT License
1.78k stars 93 forks source link

Support multipart/form-data #763

Closed sergio-milu closed 7 months ago

sergio-milu commented 7 months ago

Feature Request

Problem

I think nestia does not support multipart/form-data right now

Example

Right now this works with nestjs swagger annotations this way

  @ApiBody({
    required: true,
    type: 'multipart/form-data',
    schema: {
      type: 'object',
      properties: {
        file: {
          type: 'string',
          format: 'binary',
        },
        employerId: {
          type: 'string',
          format: 'uuid',
        },
      },
      required: ['file', 'employerId'],
    },
  })

and this generates the nest swagger

  "/api/admin/employer/process-enrollment-file": {
      "post": {
        "operationId": "EmployerAdmin_loadEmployeesFromEnrollment",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "employerId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": ["file", "employerId"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoadEmployeesFromEnrollmentResponseDto"
                }
              }
            }
          }
        },
      }
    },

could this be achieved right now?

Thanks

sergio-milu commented 7 months ago

@samchon could you shed some light here, please?

samchon commented 7 months ago

Suggest me how nestia should support it as programming code what you think.

Especially, don't forget how to express binary data that can be compatible in the client side with SDK.

sergio-milu commented 7 months ago

Suggest me how nestia should support it as programming code what you think.

Especially, don't forget how to express binary data that can be compatible in the client side with SDK.

well I'm not using client SDK, I'm only using swagger generation (replacing nestjs/swagger, that has support for multipart/form-data) and this lib Orval that also handle form-data from swagger spec I can take a look at how to implement this in the swagger generator that I have some idea of how it works, but no clue of how client SKD works

sergio-milu commented 7 months ago

Suggest me how nestia should support it as programming code what you think.

Especially, don't forget how to express binary data that can be compatible in the client side with SDK.

Maybe one way to support this in swagger is allowing a second optional param in TyperdRoute.Post to write the openapi spec that you desire (same that does nestjs with @ApiProterty), WDYT?

samchon commented 7 months ago

How to make it compatible with SDK?

sergio-milu commented 7 months ago

How to make it compatible with SDK?

I dont know how SDK works as I told you, (I use Orval for client generation from openapi spec) but maybe if that new optional parameter works in for swagger, it should also work for SDK, right? Also, supporting that in the SDK could be another issue, I want to have feature parity with what nests/swagger offers, that is support for form-data, and having that would be an improvement to match also with openapi spec. SDK could keep working the say way it is right now, but at least the swagger would be generated the right way

samchon commented 7 months ago

@sergio-milu Use like below with v2.5.3 update.

https://nestia.io/docs/core/TypedFormData/

import { TypedFormData, TypedRoute } from "@nestia/core";
import { Controller } from "@nestjs/common";

@Controller("bbs/articles")
export class BbsArticlesController {
  @TypedRoute.Post()
  public async create(
    @TypedFormData.Body() input: IBbsArticleCreate,
  ): Promise<void> {
    input;
  }
}

interface IBbsArticleCreate {
  title: string;
  body: string | null;
  thumbnail?: File | undefined;
  files: File[];
  tags: string[];
}
sergio-milu commented 7 months ago

@sergio-milu Use like below with v2.5.3 update.

https://nestia.io/docs/core/TypedFormData/

import { TypedFormData, TypedRoute } from "@nestia/core";
import { Controller } from "@nestjs/common";

@Controller("bbs/articles")
export class BbsArticlesController {
  @TypedRoute.Post()
  public async create(
    @TypedFormData.Body() input: IBbsArticleCreate,
  ): Promise<void> {
    input;
  }
}

interface IBbsArticleCreate {
  title: string;
  body: string | null;
  thumbnail?: File | undefined;
  files: File[];
  tags: string[];
}

many thanks! will try!