swagger-api / swagger-node

Swagger module for node.js
http://swagger.io
Apache License 2.0
3.97k stars 585 forks source link

Uploading files mongodb using gridfs using swagger-tools, swagger-ui-express, multer-gridfs-storage, multer #595

Open rramanadham opened 4 years ago

rramanadham commented 4 years ago

Hi everyone, I need to save large files in mongodb using gridfs.

The problem is if I use swagger validator, multer doesn't store the file in mongoDB. But I have access to my metadata parameter.

If I don't use swagger and just call my controller, I can't find the metadata parameter. Can anyone please explain what I am doing wrong.

I use swagger-tools: 0.10.4, swagger-ui-express:2.0.15, multer-gridfs-storage:3.3.0, multer: 1.4.2

Here is my swagger spec params :

"parameters": [ { "name": "file", "in": "formData", "type": "file", "required": true }, { "name": "metadata", "in": "formData", "type": "string", "required": true } //My app.js snippets using swagger middleware const path = require('path'), http = require('http'), app = require('express')(), swaggerTools = require('swagger-tools');

swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) { // Interpret Swagger resources and attach metadata to request - must be first in swagger-tools //middleware chain app.use(middleware.swaggerMetadata());

// Validate Swagger requests app.use(middleware.swaggerValidator());

// Route validated requests to appropriate controller app.use(middleware.swaggerRouter(options)); logger.info('Successfully loaded all the routes');

_.forEach(appMWs.setupSwaggerRoutes(specUtil.getBaseURL(), swaggerDoc), (middleware) => { app.use(middleware.uripath, middleware.router); });

// Start the server http.createServer(app).listen(serverPort, function () { logger.info('Your server is listening on port %d (http://localhost:%d)', serverPort, serverPort); logger.info('Swagger-ui is available on http://localhost:%d%s/api-docs', serverPort, specUtil.getBaseURL()); }); });

//my controller

const crypto = require('crypto'); const path = require('path'); const multer = require('multer'); const GridFsStorage = require('multer-gridfs-storage');

async function uploadFile(req,res,next){ //we can get metadata only if we go via swagger validator //we don't have req.body when we bypass swagger middlewares. let metadata = JSON.parse(req.body.metadata);

try{ let file = req.files.file[0]; let storage = new GridFsStorage({ url: 'mongodb://localhost:27017/file-upl?useUnifiedTopology=true&useNewUrlParser=true', cache: true, file: (req, file) => { return new Promise((resolve, reject) => { crypto.randomBytes(16, (err, buf) => { if (err) { return reject(err); } const filename = buf.toString('hex') + path.extname(file.originalname); const fileInfo = { filename: filename, bucketName: 'uploads', metadata:metadata }; resolve(fileInfo); }); }); } });

let upload = multer({storage}).single('file');

} catch(err){ next(err);

} }

Can anyone help as to what's going on? Ideally, want to use swagger validator. I want to send the key value paramaters in the payload along with the file under form-data Thanks!