File
To access files from your request, you can use the File
parameter to consume it as a stream
or SavedFile
to pump the file to disk and return a filepath.
WARNING
Requests with files are not supported in routes of type GET
.
INFO
This parameter automatically registers @fastify/multipart
in your Fastify instance.
You can further configure the plugin by passing fastifyMultipart
to the Kita plugin options.
Prerequisites
Before using the File
parameter, you need to add the ajvFilePlugin
from @fastify/multipart
when creating your Fastify instance.
import { ajvFilePlugin } from '@fastify/multipart';
import fastify from 'fastify';
const app = fastify({
ajv: { plugins: [ajvFilePlugin] } // [!code ++]
});
The above plugin registers the isFile
keyword in the AJV instance, which is used to validate the file parameter.
If you encounter the following error, it’s because the ajvFilePlugin
was not registered in your Fastify instance:
FastifyError [Error]: Failed building the validation schema for
<METHOD>
:<URL>
, due to error strict mode: unknown keyword: “isFile”
Usage
import type { File } from '@kitajs/runtime';
import { createWriteStream } from 'node:fs';
import { createBrotliCompress } from 'node:zlib';
export async function post(file: File) {
await file.file
// Do whatever you need to do with the file
// For exemple, compress it and save it to disk
.pipe(createBrotliCompress())
.pipe(createWriteStream(file.filename + '.br'));
return true;
}
{
"paths": {
"/": {
"post": {
"operationId": "postIndex",
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"properties": {
"file": {
"type": "string",
"format": "binary"
}
},
"required": ["file"],
"type": "object"
}
}
},
"required": true
},
"responses": {
"2XX": {
"description": "Default Response",
"content": {
"application/json": { "schema": { "type": "boolean" } }
}
}
}
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
You can also use the SavedFile
type to save the file to disk and return the path to the file.
import type { SavedFile } from '@kitajs/runtime';
export function post(file: SavedFile) {
return `File saved at ${file.filepath}!`;
}
{
"paths": {
"/": {
"post": {
"operationId": "postIndex",
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"properties": {
"file": {
"type": "string",
"format": "binary"
}
},
"required": ["file"],
"type": "object"
}
}
},
"required": true
},
"responses": {
"2XX": {
"description": "Default Response",
"content": {
"application/json": { "schema": { "type": "string" } }
}
}
}
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Custom names
You can also use dedicated names for the file and the field name.
import type { File, SavedFile } from '@kitajs/runtime';
export function post(
anything: File<'avatar'>,
anythingElse: SavedFile<'background'>
) {
return true;
}
{
"paths": {
"/": {
"post": {
"operationId": "postIndex",
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"properties": {
"avatar": {
"type": "string",
"format": "binary"
},
"background": {
"type": "string",
"format": "binary"
}
},
"required": ["avatar", "background"],
"type": "object"
}
}
},
"required": true
},
"responses": {
"2XX": {
"description": "Default Response",
"content": {
"application/json": { "schema": { "type": "boolean" } }
}
}
}
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38