openapistack / openapi-backend

Build, Validate, Route, Authenticate and Mock using OpenAPI
https://openapistack.co
MIT License
625 stars 83 forks source link

Support for multiple content types per route #94

Open crickford opened 4 years ago

crickford commented 4 years ago

In the OpenAPI spec, it is possible to describe a single route which accepts request bodies of different content types: Specification Swagger docs

Is this supported in openAPI backend?

In my project, I have an endpoint which accepts both application/json and multipart/form-data requests.

Either work if only the respective content type is specified in my openAPI schema, but if both are specified in the doc then only application/json requests succeed.

anttiviljami commented 4 years ago

This sounds like a bug. Care to make a test case for this @crickford ?

crickford commented 4 years ago

Added a couple of simple test cases. It looks like multipart/formdata requests are not being validated properly in any case. Perhaps I should change the issue title to "multipart/formdata support?"

tvalenta1 commented 3 years ago

Hello @anttiviljami I seem to also ran into this issue. I cannot upload any file when using openapi-backend. Neither of following request body parameters seem to be supported: requestBody: content: image/png: requestBody: content: multipart/form-data: Can this issue be looked into? Thanks

w3nl commented 5 months ago

I'm struggling to make the multipart/form-data work. Schema is no problem, but then get the information about the file that is send. How can I make it work to get the file data in the method? (dont have to save it, just have the data so I can process it)

tvalenta1 commented 4 months ago

@w3nl I'd suggest you use some npm library that correctly implements multipart/form-data request parsing. Some suggestions/samples are here for example.

w3nl commented 4 months ago

@w3nl I'd suggest you use some npm library that correctly implements multipart/form-data request parsing. Some suggestions/samples are here for example.

FYI I use Express, not Koa, but how to solve is almost the same. I tried multer, but they say, do not register as global middleware, for security reasons. You can add to the endpoint. But in openapi-backend, you register with openapi-backend the routes (api.register) Then I dont know how I can attach multer to it.

With Express you should do:

import express from 'express'
import multer from 'multer'

const app = express()
const upload = multer()

app.post('/profile', upload.none(), function (req, res, next) {
  // req.body contains the text fields
})

openapi-backend:

import { OpenAPIBackend } from 'openapi-backend'
import express from 'express'

const app = express();
app.use(express.json());

// define api
const api = new OpenAPIBackend({
  definition: openApiSpecification,
  handlers: {
    postProfile: async (c, req, res) => res.status(200).json({ operationId: c.operation.operationId })
  },
});

api.init();
app.use((req, res) => api.handleRequest(req, req, res));

But where can I attach the multer to the postProfile?

w3nl commented 4 months ago

I have it work as a global middleware, something like:

import { OpenAPIBackend } from 'openapi-backend'
import express from 'express'
import multer from 'multer'

const upload = multer()
const app = express();
app.use(express.json());

// define api
const api = new OpenAPIBackend({
  definition: openApiSpecification,
  handlers: {
    postProfile: async (c, req, res) => res.status(200).json({ operationId: c.operation.operationId })
  },
});

api.init();
app.use(upload.single('fileName'))
app.use((req, res) => api.handleRequest(req, req, res));

But multer say: https://github.com/expressjs/multer?tab=readme-ov-file#any

WARNING: Make sure that you always handle the files that a user uploads. Never add multer as a global middleware since a malicious user could upload files to a route that you didn't anticipate. Only use this function on routes where you are handling the uploaded files.

If somebody has a better solution, let me know.