question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

file upload schema error 400

See original GitHub issue

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

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:2
  • Comments:47 (19 by maintainers)

github_iconTop GitHub Comments

11reactions
kristofferostlundcommented, Feb 4, 2020

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:

const Fastify = require('fastify') // 2.11.0
const multer = require('fastify-multer') // 1.5.2
const swagger = require('fastify-swagger') // 2.5.0
const uploads = multer({ dest: '/tmp/file-uploads' })

function ajvPlugin(ajv, options) {
  ajv.addKeyword('isFileType', {
    compile: (schema, parent, it) => {
      // Change the schema type, as this is post validation it doesn't appear to error.
      parent.type = 'file'
      delete parent.isFileType
      return () => true
    },
  })

  return ajv
}

const fastify = Fastify({ logger: true, ajv: { plugins: [ajvPlugin] } })

fastify.register(multer.contentParser, { addToBody: true })
fastify.register(swagger, { exposeRoute: true })

fastify.post('/uploads', {
  schema: {
    consumes: ['multipart/form-data'],
    body: { properties: { file_1: { isFileType: true } } },
    // Shortened for the example
  },
  preHandler: uploads.single('file_1'),
  handler: async (req, reply) => req.file,
})

fastify.listen(3000)
5reactions
SkeLLLacommented, Jul 17, 2019

Here’s another workaround.

First of all as it was mentioned above we should add custom binary format:

const fastify = require('fastify')();
// ...
const ajv = new Ajv({
  // the fastify defaults (if needed)
  removeAdditional: true,
  useDefaults: true,
  coerceTypes: true,
  allErrors: true,
  nullable: true,
});
fastify.setSchemaCompiler(function(schema) {
  ajv.addFormat('binary', () => {
    // here you can do some additional checks
    return true;
  });
  return ajv.compile(schema);
});

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.

fastify.post(
    '/',
    {
      preValidation: async (req) => {
        const file = {...req.body.file};
        req.body.file = '@file';
        req.body[Symbol.for('file')] = file;
      },
      schema: {
        description: `create new file`,
        tags: ['files'],
        summary: 'create file',
        consumes: ['multipart/form-data'],
        body: {
          type: 'object',
          properties: {
            file: {
              type: 'string',
              format: 'binary',
            },
          },
        },
        response: {
         '200': { description: 'ok' },
        },
      },
    },
    async (request, reply) => {
      const files = request.body[Symbol.for('file')];
      // do something with your files.
    }
  );
Read more comments on GitHub >

github_iconTop Results From Across the Web

Upload REST API shows 400 bad request - Alfresco Hub
Returning 400 means that the request was malformed. In other words, the data stream sent by the client to the server didn't follow...
Read more >
Getting HTTP 400 error while uploading xml file - REST
I am using AS3 command file.upload(). Upload progress shows uploading till 100% but file is not uploaded on the server. I also tried...
Read more >
400 Bad Request when trying to send large file to service ...
Hi All,. I am trying to send the large file (approx 1.5GB) to the WCF service for upload using basic http streaming.
Read more >
Getting the infamous 400 error from graphql when uploading a ...
So the problem is with Apollo's internal implementation of graphql-upload. If you are autogenerating your schema I would advise you to ...
Read more >
How to Fix a 400 Bad Request Error [Causes and Fixes]
The HTTP error 400 can be caused by the file you're uploading being too large. That's usually because there's a file size limit...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found