open-api: File upload not working

Hello,

I have an endpoint documented like this:

post.apiDoc = {
    description: 'Upload an image for the category',
    operationId: 'uploadCategoryImage',
    tags: ['categories'],
    consumes: ['multipart/form-data'],
    parameters: [
        {
            name: 'image',
            in: 'formData',
            type: 'file',
            description: 'An image for this category',
            required: true
        }
    ],
    responses: {
        201: {
            description: 'Image successfully uploaded'
        },
        default: {
            description: 'Unexpected error',
            schema: {
                $ref: '#/definitions/Error'
            }
        }
    }
};

In the Swagger UI, a file upload thing is visible:

swagger

However, I keep getting this error when I send a file:

{
    path: 'image',
    errorCode: 'required.openapi.validation',
    message: 'instance requires property "image"',
    location: 'body'
}

I do have a Content-Type: multipart/form-data header in the HTTP request. Am I doing something wrong or is it a bug?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 16 (15 by maintainers)

Most upvoted comments

I got it to work with multer and a little tweak. Hopefully the following examples will be helpful for some people.

Multer is a multipart form-data handling middleware. by default it stores the upload to req.file or req.files. The express-openapi-validation logic is looking for defined files in req.body. So we need to copy the file upload to the expected position.

expressOpenapi.initialize({
  consumesMiddleware: {
    // example 1: Allow for single file upload (filename: 'file')
    'multipart/form-data'(req, res, next) {
      multer().single('file')(req, res, (err) => {
        if (err) return next(err);
        req.body.file = req.file;
        next();
      });
    }

    // example 2: Allow for any file upload
    'multipart/form-data'(req, res, next) {
      multer().any()(req, res, (err) => {
        if (err) return next(err);
        req.files.forEach(f => req.body[f.fieldname] = f);
        next();
      });
    }
  },
});

@hkors there’s currently no support for file uploads. It would be great if you could propose a solution. Most swagger frameworks that I’ve seen don’t handle this very well. I’d love express-openapi to be one of the first!