Appearance
Uploading files
This requires to have multer installed:
bash
npm install multer
npm install -D @types/multerUsing 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:
ts
import { Post, Route, FormField, UploadedFiles, UploadedFile } from 'tsoa-next'
@Route('files')
export class FilesController {
@Post('uploadFile')
public async uploadFile(@FormField() title: string, @FormField() description: string, @UploadedFiles() files: Express.Multer.File[], @UploadedFile() file: Express.Multer.File): Promise<void> {
console.log(files)
}
}Koa example:
ts
import { Post, Route, FormField, UploadedFiles, UploadedFile } from 'tsoa-next'
@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 saving on the disk with a default file location set to the OS's temp folder.
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:
ts
import { Post, Request, Route } from 'tsoa-next'
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:
ts
import { Post, Request, Route } from 'tsoa-next'
import { Request as KoaRequest } from 'koa'
import multer from 'multer'
@Route('files')
export class FilesController {
@Post('uploadFile')
public async uploadFile(@Request() request: KoaRequest): Promise<any> {
const uploadSingle = multer().single('randomFileIsHere')
await uploadSingle(request.ctx, async () => null)
// 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.
js
{
"spec": {
...
"specMerging": "recursive",
"spec": {
"paths": {
"/files/uploadFile": {
"post": {
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"in": "formData",
"name": "randomFileIsHere",
"required": true,
"type": "file"
}
]
}
}
}
}
},
"routes": {
...
}
}