diff --git a/README.md b/README.md index 9cd8c027..07ea023f 100644 --- a/README.md +++ b/README.md @@ -297,6 +297,7 @@ fastify.register(require('@fastify/multipart'), { attachFieldsToBody: 'keyValues fastify.post('/upload/files', { schema: { + consumes: ['multipart/form-data'], body: { type: 'object', required: ['myFile'], @@ -331,6 +332,7 @@ fastify.register(require('@fastify/multipart'), opts) fastify.post('/upload/files', { schema: { + consumes: ['multipart/form-data'], body: { type: 'object', required: ['myField'], @@ -372,6 +374,57 @@ The shared schema, that is added, will look like this: } ``` +### JSON Schema with Swagger + +If you want to use `@fastify/multipart` with `@fastify/swagger` and `@fastify/swagger-ui` you must add a new type called `isFile` and use custom instance of validator compiler [Docs](https://www.fastify.io/docs/latest/Reference/Validation-and-Serialization/#validator-compiler). + +```js + +const ajvFilePlugin = (ajv, options = {}) => { + return ajv.addKeyword({ + keyword: "isFile", + compile: (_schema, parent, _it) => { + parent.type = "file"; + delete parent.isFile; + return () => true; + }, + }); +}; +const fastify = require('fastify')({ + // ... + ajv: { + // add the new ajv plugin + plugins: [/*...*/ ajvFilePlugin] + } +}) +const opts = { + attachFieldsToBody: true, +}; +fastify.register(require(".."), opts); + +fastify.post( + "/upload/files", + { + schema: { + consumes: ["multipart/form-data"], + body: { + type: "object", + required: ["myField"], + properties: { + myField: { isFile: true }, + }, + }, + }, + }, + function (req, reply) { + console.log({ body: req.body }); + reply.send("done"); + } +); + +``` + + ### JSON Schema non-file field When sending fields with the body (`attachFieldsToBody` set to true), the field might look like this in the `request.body`: ```json @@ -433,6 +486,7 @@ fastify.register(require('@fastify/multipart'), opts) fastify.post('/upload/files', { schema: { + consumes: ['multipart/form-data'], body: { type: 'object', required: ['field'], diff --git a/examples/example-validation.js b/examples/example-validation.js index fe0326e0..f9fd9e65 100644 --- a/examples/example-validation.js +++ b/examples/example-validation.js @@ -8,20 +8,25 @@ const opts = { } fastify.register(require('..'), opts) -fastify.post('/upload/files', { - schema: { - body: { - type: 'object', - required: ['myField'], - properties: { - myField: { $ref: '#mySharedSchema' } +fastify.post( + '/upload/files', + { + schema: { + consumes: ['multipart/form-data'], + body: { + type: 'object', + required: ['myField'], + properties: { + myField: { $ref: '#mySharedSchema' } + } } } + }, + function (req, reply) { + console.log({ body: req.body }) + reply.send('done') } -}, function (req, reply) { - console.log({ body: req.body }) - reply.send('done') -}) +) fastify.listen({ port: 3000 }, err => { if (err) throw err diff --git a/examples/example-with-swagger.js b/examples/example-with-swagger.js new file mode 100644 index 00000000..ffebf6c0 --- /dev/null +++ b/examples/example-with-swagger.js @@ -0,0 +1,47 @@ +'use strict' +const ajvFilePlugin = (ajv, options = {}) => { + return ajv.addKeyword({ + keyword: 'isFile', + compile: (_schema, parent, _it) => { + parent.type = 'file' + delete parent.isFile + return () => true + } + }) +} +const fastify = require('fastify')({ + logger: true, + ajv: { + plugins: [ajvFilePlugin] + } +}) + +fastify.register(require('..'), { + attachFieldsToBody: true +}) +fastify.register(require('fastify-swagger')) +fastify.register(require('@fastify/swagger-ui')) +fastify.post( + '/upload/files', + { + schema: { + consumes: ['multipart/form-data'], + body: { + type: 'object', + required: ['myField'], + properties: { + myField: { isFile: true } + } + } + } + }, + function (req, reply) { + console.log({ body: req.body }) + reply.send('done') + } +) + +fastify.listen({ port: 3000 }, (err) => { + if (err) throw err + console.log(`server listening on ${fastify.server.address().port}`) +}) diff --git a/package.json b/package.json index 442b45f4..dbd6a517 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,8 @@ "@fastify/busboy": "^1.0.0", "@fastify/deepmerge": "^1.0.0", "@fastify/error": "^3.0.0", + "@fastify/swagger": "^8.3.1", + "@fastify/swagger-ui": "^1.8.0", "end-of-stream": "^1.4.4", "fastify-plugin": "^4.0.0", "hexoid": "^1.0.0",