File Helpers
Handle file uploads in your API documentation with file helper functions
File helpers provide a convenient way to define file upload schemas in your OpenAPI documentation. They work seamlessly with any schema library (VineJS, TypeBox, Zod) and integrate with the @SwaggerRequestBody decorator.
Available File Helpers
Adonis Open Swagger provides four file helper functions that generate OpenAPI-compatible file schemas:
| Function | Description |
|---|---|
openapiFile(options?) | Generic file schema (works with any validator) |
vineFile(options?) | VineJS-compatible file schema (use inside vine.object()) |
typeboxFile(options?) | TypeBox-compatible file schema (use inside Type.Object()) |
zodFile(options?) | Zod-compatible file schema (use inside z.object()) |
All functions accept the same options and produce identical output. The aliases exist for semantic consistency with your chosen schema library.
FileOptions
interface FileOptions {
description?: string; // Description of the file field
multiple?: boolean; // Accept multiple files (default: false)
minItems?: number; // Min files (only when multiple: true)
maxItems?: number; // Max files (only when multiple: true)
}Basic Usage
Single File Upload
import { openapiFile } from "adonis-open-swagger";
openapiFile({ description: "Profile picture" });
// Generates: { type: "string", format: "binary", description: "Profile picture" }Multiple Files Upload
import { openapiFile } from "adonis-open-swagger";
openapiFile({
description: "Gallery images",
multiple: true,
minItems: 1,
maxItems: 10,
});
// Generates: {
// type: "array",
// items: { type: "string", format: "binary" },
// description: "Gallery images",
// minItems: 1,
// maxItems: 10
// }Integration with Schema Libraries
VineJS
import { SwaggerRequestBody, SwaggerInfo, vineFile } from "adonis-open-swagger";
import vine from "@vinejs/vine";
export default class CampaignsController {
@SwaggerInfo({
tags: ["Campaigns"],
summary: "Create campaign with file upload",
description: "Upload a CSV file with customer data",
})
@SwaggerRequestBody(
"Campaign data with file",
vine.object({
name: vine.string(),
file: vineFile({ description: "CSV file with customers" }),
}),
{ contentType: "multipart/form-data" }
)
async store({ request }: HttpContext) {
// Handle file upload
}
}TypeBox
import {
SwaggerRequestBody,
SwaggerInfo,
typeboxFile,
} from "adonis-open-swagger";
import { Type } from "@sinclair/typebox";
export default class UploadsController {
@SwaggerInfo({
tags: ["Uploads"],
summary: "Upload document",
})
@SwaggerRequestBody(
"Document upload",
Type.Object({
title: Type.String(),
document: typeboxFile({ description: "PDF document" }),
}),
{ contentType: "multipart/form-data" }
)
async upload({ request }: HttpContext) {
// Handle file upload
}
}Zod
import { SwaggerRequestBody, SwaggerInfo, zodFile } from "adonis-open-swagger";
import { z } from "zod";
export default class MediaController {
@SwaggerInfo({
tags: ["Media"],
summary: "Upload media files",
})
@SwaggerRequestBody(
"Media upload",
z.object({
caption: z.string(),
images: zodFile({
description: "Image files",
multiple: true,
maxItems: 5,
}),
}),
{ contentType: "multipart/form-data" }
)
async upload({ request }: HttpContext) {
// Handle file upload
}
}Content Types
When using file helpers, you must set the appropriate content type in @SwaggerRequestBody:
| Content Type | Use Case |
|---|---|
multipart/form-data | File uploads and mixed data |
@SwaggerRequestBody(
"File upload with metadata",
vine.object({
name: vine.string(),
file: vineFile({ description: "Upload file" }),
}),
{ contentType: "multipart/form-data" } // Required for file uploads
)Complete Example
Here's a complete example of a file upload endpoint with full documentation:
import {
SwaggerInfo,
SwaggerRequestBody,
SwaggerResponse,
vineFile,
} from "adonis-open-swagger";
import vine from "@vinejs/vine";
import type { HttpContext } from "@adonisjs/core/http";
export default class DocumentsController {
@SwaggerInfo({
tags: ["Documents"],
summary: "Upload documents",
description: "Upload one or more documents with metadata",
})
@SwaggerRequestBody(
"Document upload payload",
vine.object({
title: vine.string().minLength(1).maxLength(255),
description: vine.string().optional(),
files: vineFile({
description: "Document files (PDF, DOCX)",
multiple: true,
minItems: 1,
maxItems: 10,
}),
}),
{ contentType: "multipart/form-data" }
)
@SwaggerResponse(201, "Documents uploaded successfully")
@SwaggerResponse(400, "Invalid file format")
@SwaggerResponse(413, "File size too large")
async store({ request, response }: HttpContext) {
const files = request.files("files");
// Process uploaded files
return response.created({ message: "Documents uploaded" });
}
}Last updated on