fastify-swagger: file upload schema error 400
Hi, when i define the schema consumer in endpoint /upload to ‘multipart/form-data’ for uploading file i dont know wich is the schema structure body for passing the base64 string or the file that i need to upload.
If y define the schema:
schema: {
description: 'Upload file',
tags: ['Info'],
consumes: [ 'multipart/form-data' ],
summary: 'Upload the file to the server',
body: {
type: 'object',
properties: {
file: {type: 'string'}
}
},
response: {
200: {
description: 'Succesful response',
type: 'boolean'
}
}
}
when i send the post get the error:
{
"statusCode": 400,
"error": "Bad Request",
"message": "body should be object"
}
I fetch in the dynamic.js code looking for the solution but i dont get with it.
Can you help me?
PD: Im sorry if this is not the place for this kind of issues.
Thx
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 47 (19 by maintainers)
I found another workaround based on @SkeLLLa’s suggestion, where I add a small ajv plugin to fastify, which I believe might be a little bit less intrusive?
Below is a fully functioning example:
Here’s another workaround.
First of all as it was mentioned above we should add custom
binary
format:Afterwards in your routes we should do some hack that will allow to pass ajv validation for string type. So we need
preValidation
hook where we’ll replace what’s come from user with some string, so ajv will validate it and hide original file inside non-enumerable property.I have managed to get file uploads work for my use case, its a little bit hacky.
I had a couple of issues, firstly swagger wants type to be file, but as Ajv uses that and doesn’t allow custom types, there was either altering the schema post validation or altering the fastify-swagger module code to look for another property and output that as the type property.
Secondly, the multipart module didn’t add the files data to the request body prior to the schema validation which caused errors about the body being expected as an object. So i created a custom content type parser to build the request body from the stream.
So far my solution seems to be working, although i have not tested it with larger files or in different scenarios.
If it helps anyone, here’s my code;
Then just added the isFileType property into the schema;
Can you please get a stacktrace for that?
I think we should add a custom keyword to Fastify ajv: https://github.com/epoberezkin/ajv#defining-custom-keywords.
We would have to replace the stock ajv instance with a custom one with the new keyword: https://github.com/fastify/fastify/blob/master/docs/Validation-and-Serialization.md#schema-compiler.
Would you like to send a PR to this module? It think it’s something that we should ship.
cc @delvedor
I’m not that expert on swagger.
@sarneeh I think that adding a new key could create misunderstanding.
The content type defines “what and how” the data are written in the body of the HTTP request. In fact, the standard talk about the “body” also with the multipart content type.
So what we do here is translating the multipart body, to the json format (that is the easiest format to read the data) and we apply the validation on it.
If we would add a new key for the multipart, we should add a key for each content-types out there and develop a validator that can manage that type of format: this could be a HUGE work.
For this reason, I think that translating the multipart to a json-body is a good compromise