This requires to have multer installed:
yarn add multer
yarn add -D @types/multerThe 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
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": {
...
}
}