Skip to content

Latest commit

 

History

History
140 lines (117 loc) · 3.52 KB

File metadata and controls

140 lines (117 loc) · 3.52 KB

Uploading files

This requires to have multer installed:

yarn add multer
yarn add -D @types/multer

Using the UploadedFile / UploadedFiles decorator

The simplest way to add support for file upload is by adding @UploadedFiles or @UploadedFile as a parameter decorator. This loads multer allowing multipart/form-data submissions to work. @FormField can be used to access other multipart form fields.

Express example:

import { Post, Route, FormField, UploadedFiles, UploadedFile, File } from "tsoa";

@Route("files")
export class FilesController {
  @Post("uploadFile")
  public async uploadFile(
      @FormField() title: string,
      @FormField() description: string,
      @UploadedFiles() files: File[],
      @UploadedFile() file: File,
  ): Promise<void> {
    console.log(files);
  }
}

Koa example:

import { Post, Route, FormField, UploadedFiles, UploadedFile, File } from "tsoa";

@Route("files")
export class FilesController {
  @Post("uploadFile")
  public async uploadFile(
      @FormField() title: string,
      @FormField() description: string,
      @UploadedFiles() files: File[],
      @UploadedFile() file: File,
  ): Promise<void> {
    console.log(files);
  }
}

Note, that using the decorator defaults to store upload file content in memory. Access the content using buffer property

Custom multer upload

To customize the multer upload, you have to use multer inside a controller resource.

To use it with Express, call handleFile and pass the express Request to resolve 'file'. This also handles multipart/form-data. A quick sample:

import { Post, Request, Route } from "tsoa";
import express from "express";
import multer from "multer";

@Route("files")
export class FilesController {
  @Post("uploadFile")
  public async uploadFile(@Request() request: express.Request): Promise<any> {
    await this.handleFile(request);
    // file will be in request.randomFileIsHere, it is a buffer
    return {};
  }

  private handleFile(request: express.Request): Promise<any> {
    const multerSingle = multer().single("file");
    return new Promise((resolve, reject) => {
      multerSingle(request, undefined, async (error) => {
        if (error) {
          reject(error);
        }
        resolve();
      });
    });
  }
}

To use it with Koa, pass Koa's Request context object to resolve 'file'. This also handles multipart/form-data. A quick sample:

import { Post, Request, Route } from "tsoa";
import { Request as koaRequest } from "koa";
import multer from "multer";

@Route("files")
export class FilesController {
  @Post("uploadFile")
  public async uploadFile(@Request() koaRequest: Request): Promise<any> {
    const multer = multer().single("file");
    await multer(request.ctx, async () => null);
    const multerSingle = multer().single("randomFileIsHere");
    // file will be in request.randomFileIsHere, it is a buffer
    return {};
  }
}

The according OpenAPI definition can be merge-overwritten inside tsoa.json. Here is a quick sample, what the previous request should look like.

{
  "spec": {
    ...
    "specMerging": "recursive",
    "spec": {
      "paths": {
        "/files/uploadFile": {
          "post": {
            "consumes": [
              "multipart/form-data"
            ],
            "parameters": [
              {
                "in": "formData",
                "name": "randomFileIsHere",
                "required": true,
                "type": "file"
              }
            ]
          }
        }
      }
    }
  },
  "routes": {
     ...
  }
}