上传文件 - nodejs with typescript and tsoa and swagger
uploading files - nodejs with typescript and tsoa and swagger
我用 nodejs 和 express 构建了一个网络 api。我使用 tsoa 来生成我的路线和一个 swagger.json 文件。
我希望能够通过 swagger 登陆页面上传文件。我按照此页面上的说明操作:https://tsoa-community.github.io/docs/file-upload.html
我的 tsoa.json 看起来像这样:
{
"entryFile": "src/app.ts",
"noImplicitAdditionalProperties": "throw-on-extras",
"controllerPathGlobs": [
"src/**/*.controller.ts"
],
"spec": {
"basePath" : "/",
"description": "",
"outputDirectory": "dist/api/public",
"specVersion": 3,
"specMerging": "recursive",
"paths": {
"/admin/commands/create": {
"post": {
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"in": "formData",
"name": "randomFileIsHere",
"required": true,
"type": "file"
}
]
}
}
}
},
"routes": {
"routesDir": "src/api"
}
}
我的控制器:
@Tags("Admin Commands")
@Route("admin/commands")
export class AdminCommandController extends Controller
{
@Post('create')
public async CreateCommand(@Request() request: express.Request): Promise<void>
{
try{
await this.handleFile(request);
}
catch {
throw new Error("Error uploading file.");
}
console.log("No error");
}
private handleFile(request: express.Request): Promise<any> {
const multerSingle = multer().single("randomFileIsHere");
return new Promise((resolve, reject) => {
multerSingle(request, undefined, async (error: Error) => {
if (error) {
reject("error");
}
resolve("file will be in request.randomFileIsHere");
});
});
}
}
但是当我使用 tsoa swagger 命令生成 swagger.json 时,multipart/form-data 没有添加到我的 swagger.json。如果我手动将 multipart/form-data 添加到我的 swagger.json,我 swagger 登陆页面上的输入字段是文本字段而不是文件字段。
"paths": {
"/admin/commands/create": {
"post": {
"operationId": "CreateCommand",
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"in": "formData",
"name": "randomFileIsHere",
"required": true,
"type": "file"
}
],
"responses": {
"204": {
"description": "No content"
}
},
"tags": [
"Admin Commands"
],
"security": []
}
}
}
我错过了什么或做错了什么?此外,如果这可行,我如何从请求中提取文件。文档说文件将被添加到请求对象的 randomFileIsHere 属性 中,但是如果我调用 request.randomFileIsHere 显然会抛出错误。
我也试着按照官方文档。我能够保存上传的文件,但代码对我来说看起来并不干净。然后我意识到有一个 @UploadedFile 装饰器。您可以添加它并直接读取文件。
@Post("profile-photo")
public async uploadProfilePhoto(@UploadedFile() profilePhoto) {
console.log(profilePhoto)
}
使用 HTTP 测试工具,如 Postman,定义一个名为“profilePhoto”的字段和 select 一个文件。你应该可以在服务器端看到它。
我用 nodejs 和 express 构建了一个网络 api。我使用 tsoa 来生成我的路线和一个 swagger.json 文件。 我希望能够通过 swagger 登陆页面上传文件。我按照此页面上的说明操作:https://tsoa-community.github.io/docs/file-upload.html
我的 tsoa.json 看起来像这样:
{
"entryFile": "src/app.ts",
"noImplicitAdditionalProperties": "throw-on-extras",
"controllerPathGlobs": [
"src/**/*.controller.ts"
],
"spec": {
"basePath" : "/",
"description": "",
"outputDirectory": "dist/api/public",
"specVersion": 3,
"specMerging": "recursive",
"paths": {
"/admin/commands/create": {
"post": {
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"in": "formData",
"name": "randomFileIsHere",
"required": true,
"type": "file"
}
]
}
}
}
},
"routes": {
"routesDir": "src/api"
}
}
我的控制器:
@Tags("Admin Commands")
@Route("admin/commands")
export class AdminCommandController extends Controller
{
@Post('create')
public async CreateCommand(@Request() request: express.Request): Promise<void>
{
try{
await this.handleFile(request);
}
catch {
throw new Error("Error uploading file.");
}
console.log("No error");
}
private handleFile(request: express.Request): Promise<any> {
const multerSingle = multer().single("randomFileIsHere");
return new Promise((resolve, reject) => {
multerSingle(request, undefined, async (error: Error) => {
if (error) {
reject("error");
}
resolve("file will be in request.randomFileIsHere");
});
});
}
}
但是当我使用 tsoa swagger 命令生成 swagger.json 时,multipart/form-data 没有添加到我的 swagger.json。如果我手动将 multipart/form-data 添加到我的 swagger.json,我 swagger 登陆页面上的输入字段是文本字段而不是文件字段。
"paths": {
"/admin/commands/create": {
"post": {
"operationId": "CreateCommand",
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"in": "formData",
"name": "randomFileIsHere",
"required": true,
"type": "file"
}
],
"responses": {
"204": {
"description": "No content"
}
},
"tags": [
"Admin Commands"
],
"security": []
}
}
}
我错过了什么或做错了什么?此外,如果这可行,我如何从请求中提取文件。文档说文件将被添加到请求对象的 randomFileIsHere 属性 中,但是如果我调用 request.randomFileIsHere 显然会抛出错误。
我也试着按照官方文档。我能够保存上传的文件,但代码对我来说看起来并不干净。然后我意识到有一个 @UploadedFile 装饰器。您可以添加它并直接读取文件。
@Post("profile-photo")
public async uploadProfilePhoto(@UploadedFile() profilePhoto) {
console.log(profilePhoto)
}
使用 HTTP 测试工具,如 Postman,定义一个名为“profilePhoto”的字段和 select 一个文件。你应该可以在服务器端看到它。