I am using swagger with Node and now stuck at multiple file upload part as i am able to get my files on server using swagger-fileupload-docs document page.
middleware is multer
and i use below settings in my server.ts file or in the main file from where execution starts
import 'reflect-metadata';
import bodyParser from 'body-parser';
import cors from 'cors';
import express from 'express';
import bunyanMiddleware from 'express-bunyan-logger';
import fg from 'fast-glob';
import helmet from 'helmet';
import { createConnection } from 'typeorm';
import config from './config';
import ErrorHandler from './middlewares/errorHandler';
import logger from './utils/logger';
async function start(): Promise<void> {
logger.info('Starting server...');
await createConnection();
const app = express();
// Register middlewares
const appUrl = new URL(config.app.url);
app.use(cors({
origin: config.env === 'production' ? appUrl.origin : '*',
}));
app.use(helmet());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bunyanMiddleware({
logger,
parseUA: false,
excludes: ['response-hrtime', 'req-headers', 'res-headers'],
format: ':incoming :method :url :status-code',
}));
// Register routes
const routes = await fg('./routes/*.(ts|js)', { cwd: __dirname });
for (const routePath of routes) {
const { default: router } = await import(routePath);
if (typeof (router) === 'function') app.use(config.server.basePath, router);
}
// Error handler must come last...
app.use(ErrorHandler);
// Kick it off!
app.listen(config.server.port, async () => {
logger.info({ port: config.server.port }, 'Hey! I\'m listening...');
});
}
start();
and now in the ROUTE file for product.ts
code is given below using multer
import Joi from '@hapi/joi';
import express, { Router } from 'express';
import { ProductStatus, Role, } from '../models/enums';
import { authorize } from '../middlewares/authorize';
import { wrapAsync } from '../utils/asyncHandler';
import { Request, isUserReq } from './interfaces';
import { createBrand, deleteBrand, getAllBrands, updateBrand } from '../services/brand';
import multer from 'multer';
import { createProduct, deleteProduct, getAllProducts, updateProduct } from '../services/product';
const upload = multer({ dest: '/tmp/' })
const router = Router();
router.post('/products', authorize(), upload.array('imagesPath'), wrapAsync(async (req: Request, res: express.Response) => {
var files = req.files;
const { name, price, status, categoryId, vendorId } = await Joi
.object({
name: Joi.string().trim().min(3).max(50).required().label('Name'),
price: Joi.number().min(1).max(10000).required().label('Price'),
status: Joi.string().valid(ProductStatus.IN_STOCK, ProductStatus.OUT_OF_STOCK, ProductStatus.RUNNING_LOW).required().label('Status'),
categoryId: Joi.string().trim().uuid().required().label('Category ID'),
vendorId: Joi.string().trim().uuid().required().label('Vendor ID'),
})
.validateAsync(req.body);
But i am not able to iterate over req.files as it is giving below error
and my swagger doc are as follow.
/**
* @swagger
* /products:
* post:
* tags:
* - Product
* summary: Create a product
* consumes:
* - multipart/form-data
* security:
* - JWT: []
* requestBody:
* required: true
* content:
* multipart/form-data:
* schema:
* type: object
* properties:
* name:
* description: Product name
* type: string
* price:
* description: Product price
* type: string
* status:
* description: Product status
* type: string
* enum: [OUT_OF_STOCK, IN_STOCK, RUNNING_LOW]
* imagesPath:
* description: Product logo
* type: array
* items:
* type: string
* format: binary
* categoryId:
* type: string
* vendorId:
* type: string
* produces:
* - multipart/form-data
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Product'
* example:
* id: 2efa52e2-e9fd-4bd0-88bc-0132b2e837d9
* name: Product 1
* price: 25
* status: IN_STOCK
* imagesPath: ['https://${config.s3.Images}.s3.amazonaws.com/${req.file.originalname}']
* categoryId: 2efa52e2-e9fd-4bd0-88bc-0132b2e837d9
* vendorId: 4efa52e5-e6fd-4bd0-68bc-0132b2e83ww49
* 401:
* $ref: '#/components/responses/UnauthorizedError'
* 409:
* $ref: '#/components/responses/ConflictError'
* 500:
* $ref: '#/components/responses/InternalError'
*/
OPENAPI POST DEFINATIONS that i am using for my api and using format as binary.
use typeof req.files
to check if its array
if its not array then you can use any of these to convert it to array and then use forEach:
Array(req.files).forEach(f => console.log(f))
Array.from(req.files).forEach(f => console.log(f))
[].forEach.call(req.files, console.log)