swagger-api/swagger-node

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

rramanadham opened this issue · 0 comments

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!