This is related, but different from #710. I'm not sure that there is a bug, maybe I just need use these packages differently as I'm using them at quite low level (with manual parsing of request body and etc).
I'm trying to validate such a request on AWS Lambda. Due to platform validations, I'm getting raw body, so I parse it with lambda-multipart-parser and validate with openapi-request-validator with code like this:
import OpenAPIRequestValidator } from "openapi-request-validator"
import { parse as parseMultipart } from "lambda-multipart-parser"
const { files, ...plainFields } = await parseMultipart(event)
const fileFields = Object.fromEntries(files.map(file => [file.fieldname, file.content.toString()]))
data = { ...plainFields, ...fileFields }
(new OpenAPIRequestValidator({…})).validateRequest({
headers: headers,
body: data,
params: event.pathParameters,
query: event.queryStringParameters,
})
openapi-request-validator validates request and doesn't pass requests with file or someId missing
Actual result
openapi-request-validator passes requests with missing non-nullable fields
Workaround
Then I went to openapi-request-validator source and found that it expects for multipart requests that all input fields should be declared as input formdata parameters instead of request body (see this test case)
So I tried to change schema in a way that openapi-request-validator should understand: replaced request body with parameters
And success! Now it is being validated as expected.
But Swagger Editor tells me that this schema is now invalid:
Structural error at paths./fileAttachments.post.parameters.0.in
should be equal to one of the allowed values
allowedValues: path, query, header, cookie
(and 2 more errors)
To complete this workaround I had to preprocess schema, converting multipart bodies into formData parameters on schema load with code like this.
Some hacky TypeScript code
```typescript
import yaml from "js-yaml"
import { readFileSync } from "fs"
import $RefParser from "@apidevtools/json-schema-ref-parser"
import { OpenAPIV3 } from "openapi-types"
type OpenApiHttpMethods = "get" | "post" | "put" | "delete" | "options" | "head" | "patch" | "trace"
const apiSpec = yaml.safeLoad(readFileSync("./apiSchema.yaml").toString())
async function preprocessOpenapiSpec(apiSpec: OpenAPIV3.Document): Promise {
const schema = await $RefParser.dereference(apiSpec)
// Replace multipart request body with formData parameters for validation
for (const methods of Object.values(schema.paths)) {
for (const method of ["get", "post", "put", "delete", "options", "head", "patch", "trace"]) {
const methodOptions = methods[method]
if (!methodOptions) continue
const reqBody = methodOptions?.requestBody
if (reqBody?.content && "multipart/form-data" in reqBody.content) {
const props = (reqBody.content["multipart/form-data"].schema)?.properties
if (!props) continue
methodOptions.parameters ||= []
for (const [name, subschema] of Object.entries(props)) {
const required = ("nullable" in subschema) ? !subschema.nullable : false
methodOptions.parameters.push({ name, in: "formData", required, schema: subschema })
}
delete methodOptions?.requestBody
}
}
}
return schema
}
```
Question
Is there a bug in openapi-request-validator? If so, can you point me where to start fixing it, so I can prepare a pull request (I'm not sure where to start, honestly)
Or should I somehow preprocess schema or body using some other package from this suite?
This is related, but different from #710. I'm not sure that there is a bug, maybe I just need use these packages differently as I'm using them at quite low level (with manual parsing of request body and etc).
The problem
In OpenAPI 3
multipart/form-data
requests should be declared as objects inrequestBody
according to Describing Request Body / File Uploads docs:I'm trying to validate such a request on AWS Lambda. Due to platform validations, I'm getting raw body, so I parse it with lambda-multipart-parser and validate with openapi-request-validator with code like this:
Which gives me following object as a
body
:Expected result
openapi-request-validator
validates request and doesn't pass requests withfile
orsomeId
missingActual result
openapi-request-validator
passes requests with missing non-nullable fieldsWorkaround
Then I went to openapi-request-validator source and found that it expects for multipart requests that all input fields should be declared as input
formdata
parameters instead of request body (see this test case)So I tried to change schema in a way that openapi-request-validator should understand: replaced request body with parameters
apiSchema.yml with formData parameters
```yaml openapi: 3.0.3 info: title: Sample Application API version: v1 paths: /fileAttachments: post: parameters: - name: someId in: formData required: true schema: type: string - name: status in: formData required: false schema: type: string - name: file in: formData required: true schema: type: string format: binary responses: 204: description: Success ```And success! Now it is being validated as expected.
But Swagger Editor tells me that this schema is now invalid:
To complete this workaround I had to preprocess schema, converting multipart bodies into
formData
parameters on schema load with code like this.Some hacky TypeScript code
```typescript import yaml from "js-yaml" import { readFileSync } from "fs" import $RefParser from "@apidevtools/json-schema-ref-parser" import { OpenAPIV3 } from "openapi-types" type OpenApiHttpMethods = "get" | "post" | "put" | "delete" | "options" | "head" | "patch" | "trace" const apiSpec =Question
Is there a bug in openapi-request-validator? If so, can you point me where to start fixing it, so I can prepare a pull request (I'm not sure where to start, honestly)
Or should I somehow preprocess schema or body using some other package from this suite?
Originally posted by @Envek in https://github.com/kogosoftwarellc/open-api/issues/710#issuecomment-788128653