Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File upload not working #29

Closed
hkors opened this issue Mar 30, 2016 · 16 comments
Closed

File upload not working #29

hkors opened this issue Mar 30, 2016 · 16 comments

Comments

@hkors
Copy link

hkors commented Mar 30, 2016

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?

@hkors
Copy link
Author

hkors commented Mar 30, 2016

I can now receive the file by adding 'x-express-openapi-disable-validation-middleware': true to this documentation, but I suppose this shouldn't be the solution...

@jsdevel
Copy link
Contributor

jsdevel commented Mar 30, 2016

@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!

@mghignet
Copy link
Contributor

mghignet commented Oct 4, 2016

Hi!

The issue should be fixed now, I had the same problem.
See #55

@jsdevel
Copy link
Contributor

jsdevel commented Oct 4, 2016

Thanks @mghignet ! I've published #55 as v0.30.0. If you have the time, could you add a sample project to the test suite showing a file upload example?

@jsdevel
Copy link
Contributor

jsdevel commented Oct 4, 2016

@hkors if you're able to try again with the latest version it would be appreciated. I'll leave this issue open until we have confirmation that file uploads work.

@mghignet
Copy link
Contributor

mghignet commented Oct 5, 2016

Actually the bug is still present.
The issue is that we need to validate the presence of some fields (typically, a file) in formData, but it's not as easy as for a body or a query string.
The only workaround I've found is to remove the "required" property from formData parameters.

@mghignet
Copy link
Contributor

mghignet commented Oct 5, 2016

kogosoftwarellc/express-openapi-validation@0096f84
I've commented on this.
The "quick and dirty" solution I see would be to remove the piece of code I commented to disable errors for formData fields, since we're not able to validate them correctly.
It means "required" property (and maybe some other ones) would be ineffective.
What do you think?

@jsdevel
Copy link
Contributor

jsdevel commented Jan 25, 2017

@mghignet sorry for the late reply. Holidays and election happened here in the states. Barely getting back in the swing of things.

Whatever we need to do to get file uploads working, as long as the tests pass, I say we do it! Can you submit a PR?

@alrik
Copy link
Contributor

alrik commented Jan 2, 2018

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();
      });
    }
  },
});

@jsdevel
Copy link
Contributor

jsdevel commented Jan 2, 2018

Nice @alrik ! Can you by chance update the README with this example, and possibly create a test (i.e. can you add multer as a devDependency to show that it works)?

@alrik
Copy link
Contributor

alrik commented Jan 3, 2018

Hey @jsdevel sure. I'll add an example to the readme and add some tests when i got some spare time. Could you assign me the issue, so that i don't forget about it?

@jsdevel jsdevel assigned jsdevel and unassigned jsdevel Jan 3, 2018
@jsdevel
Copy link
Contributor

jsdevel commented Jan 3, 2018

@alrik looks like I'm unable to assign to non-project collaborators. If you own an issue, I can assign it to you. Want to open a new issue here about a missing example in the README for file uploads? I should be able to assign that to you.

@nigelkirby
Copy link
Contributor

I submit that this issue is addressed satisfactorily by #105

@jsdevel
Copy link
Contributor

jsdevel commented May 25, 2018

Agreed. Thanks @simpgeek! @hkors let us know if you disagree.

@jsdevel jsdevel closed this as completed May 25, 2018
@mbsimonovic
Copy link
Contributor

i'm getting an error trying to test this with curl. The spec is:

    /upload/:
        post:
            summary: Create NEW files
            operationId: upload
            requestBody:
                required: true
                content:
                    multipart/form-data:
                        schema:
                            type: object
                            properties:
                                docs:
                                    type: array
                                    items:
                                        type: string
                                        format: binary

and express-openapi is initialised as suggested:

 '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);
                return next(); // this executes correctly
            });
        }

Hitting the app with curl:
curl "http://localhost:3000/upload/" -H "accept: */*" -H "Content-Type: multipart/form-data" -F docs=@package.json , fails with the following error (the endpoint never gets called):

Unsupported Content-Type multipart/form-data; boundary=------------------------2a07fe1e704ec1f5

The same happens with superagent/supertest and postman. Any hints?

@jsdevel
Copy link
Contributor

jsdevel commented Dec 31, 2018

@mbsimonovic please file a new issue. that appears to be related to V3 which wasn't published at the time this issue was created.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants