fastify-swagger-ui icon indicating copy to clipboard operation
fastify-swagger-ui copied to clipboard

With multipart/form-data and swagger-ui unable to uplaod a file from Swagger UI

Open giuseppe229 opened this issue 8 months ago • 2 comments

Prerequisites

  • [X] I have written a descriptive issue title
  • [X] I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.26.1

Plugin version

3.0.0

Node.js version

21.7.3

Operating system

Windows

Operating system version (i.e. 20.04, 11.3, 10)

11

Description

I'm trying to upload multiple files in a post API call with multipart/form-data I'm not able to do it neither in the swagger-ui or remotely (also with postman) I'm getting the error: Error: body/files must be string\n

If I change my route schema definition from files: { type: 'array', items: { type: 'string', format: 'binary' }, }, to files: { type: 'array', items: { format: 'binary' }, },

it works fine with postman but i'm not able to upload the file directly from the swagger UI

This is my app.js file:


const path = require('node:path')
const AutoLoad = require('@fastify/autoload')

// Pass --options via CLI arguments in command to enable these options.
const options = {}

module.exports = async function (fastify, opts) {

  fastify.register(require("@fastify/multipart"), { addToBody: true })

  // Register @fastify/swagger plugin
  await fastify.register(require('@fastify/swagger'), {
    openapi: {
      openapi: '3.0.0',
      info: {
        title: 'Local File Loader',
        description: 'Uploading one or more file on ***',
        version: '0.1.0'
      },
      servers: [
        {
          url: 'http://localhost:3000',
          description: 'Development server'
        }
      ],
      tags: [
        { name: 'load', description: 'Endpoint to uplaod files' }
      ],
      consumes: ['multipart/form-data'],
      externalDocs: {
        url: 'https://swagger.io',
        description: 'Find more info here'
      }
    }
  })

  // Register @fastify/swagger-ui plugin
  await fastify.register(require('@fastify/swagger-ui'), {
    routePrefix: '/documentation',
    uiConfig: {
      docExpansion: 'full',
      deepLinking: false
    },
    uiHooks: {
      onRequest: function (request, reply, next) { next() },
      preHandler: function (request, reply, next) { next() }
    },
    staticCSP: true,
    transformStaticCSP: (header) => header,
    transformSpecification: (swaggerObject, request, reply) => { return swaggerObject },
    transformSpecificationClone: true
  })

  // Do not touch the following lines

  // This loads all plugins defined in plugins
  // those should be support plugins that are reused
  // through your application
  fastify.register(AutoLoad, {
    dir: path.join(__dirname, 'plugins'),
    options: Object.assign({}, opts)
  })

  // This loads all plugins defined in routes
  // define your routes in one of these
  fastify.register(AutoLoad, {
    dir: path.join(__dirname, 'routes'),
    options: Object.assign({}, opts)
  })

  // Ensure the swagger documentation is generated before the server starts
  // await fastify.ready()
  // fastify.swagger()
}

module.exports.options = options

This is my route to upload files:


const { uplaodFile } = require('../../controllers/load');


module.exports = async function (fastify, opts) {
    // File upload route
    fastify.post('/', {
        schema: {
            summary: 'Upload multiple files',
            description: 'Endpoint to upload multiple files',
            consumes: ['multipart/form-data'],
            tags: ['load'],
            body: {
                type: 'object',
                properties: {
                    files: {
                        type: 'array',
                        items: { type: 'string', format: 'binary' },
                    },
                    filesPaths: {
                        type: 'array',
                        items: {
                            properties: {
                                fileName: { type: "string" },
                                filePath: { type: "string" },
                            }
                        }
                    }
                },
            },
            response: {
                200: {
                    description: 'Successful response',
                    type: 'object',
                    properties: {
                        status: { type: 'string' },
                    },
                },
            },
        },
        handler: uplaodFile
    });
}

Link to code that reproduces the bug

No response

Expected Behavior

No response

giuseppe229 avatar Jun 03 '24 21:06 giuseppe229