The Bodyparser module re-exports all functionality from @adonisjs/bodyparser, providing middleware for parsing HTTP request bodies in various formats.
Import
import { BodyParserMiddleware } from '@adonisjs/core/bodyparser'
import type { BodyParserConfig } from '@adonisjs/core/bodyparser'
Overview
The Bodyparser module provides middleware for parsing incoming HTTP request bodies. It supports JSON, URL-encoded forms, multipart forms (file uploads), and raw text payloads.
Middleware
BodyParserMiddleware
The main body parser middleware that automatically parses request bodies based on the Content-Type header.
Supported Content Types
Parses JSON payloads and makes them available via request.body()
application/x-www-form-urlencoded
Parses URL-encoded form data and makes it available via request.body()
Parses multipart form data including file uploads. Files are available via request.file() and other fields via request.body()
Parses raw text payloads and makes them available via request.raw()
Registration
The middleware is typically registered in the global middleware stack:
// start/kernel.ts
import router from '@adonisjs/core/services/router'
import BodyParserMiddleware from '@adonisjs/core/bodyparser/bodyparser_middleware'
router.use([BodyParserMiddleware])
HttpContext Methods
Once the bodyparser middleware is registered, the following methods become available on the request object:
request.body()
Returns the parsed request body.
The parsed request body as an object
import type { HttpContext } from '@adonisjs/core/http'
export default class UsersController {
async store({ request, response }: HttpContext) {
const body = request.body()
// body contains all form fields and JSON data
const { name, email } = request.only(['name', 'email'])
// ...
}
}
request.file()
Returns an uploaded file from a multipart request.
The field name of the uploaded file
Optional validation optionsMaximum file size (e.g., ‘2mb’, 2048)
The uploaded file object or null if not found
export default class UsersController {
async uploadAvatar({ request, response }: HttpContext) {
const avatar = request.file('avatar', {
size: '2mb',
extnames: ['jpg', 'png', 'jpeg']
})
if (!avatar) {
return response.badRequest({ message: 'Avatar is required' })
}
if (!avatar.isValid) {
return response.badRequest({ errors: avatar.errors })
}
await avatar.move('uploads/avatars')
}
}
request.files()
Returns all uploaded files from a multipart request.
The field name of the uploaded files (for array uploads)
Optional validation options (same as request.file())
Array of uploaded file objects
export default class PostsController {
async uploadImages({ request, response }: HttpContext) {
const images = request.files('images', {
size: '5mb',
extnames: ['jpg', 'png', 'jpeg', 'webp']
})
for (const image of images) {
if (!image.isValid) {
return response.badRequest({ errors: image.errors })
}
await image.move('uploads/images')
}
}
}
request.allFiles()
Returns all uploaded files from all fields.
Object with field names as keys and MultipartFile objects as values
export default class DocumentsController {
async upload({ request, response }: HttpContext) {
const allFiles = request.allFiles()
for (const [fieldName, file] of Object.entries(allFiles)) {
if (file.isValid) {
await file.move(`uploads/${fieldName}`)
}
}
}
}
request.raw()
Returns the raw request body as a string.
export default class WebhooksController {
async handle({ request, response }: HttpContext) {
const rawBody = request.raw()
// Use raw body for signature verification
const signature = request.header('x-webhook-signature')
const isValid = verifySignature(rawBody, signature)
if (!isValid) {
return response.unauthorized({ message: 'Invalid signature' })
}
// Process webhook
}
}
MultipartFile
The MultipartFile class represents an uploaded file.
Properties
The field name used in the form
The original filename provided by the client
The MIME type of the file
Whether the file passed validation
Array of validation errors
Whether validation has been performed
Methods
move()
Moves the uploaded file to a permanent location.
The directory path where the file should be moved
Optional configurationCustom filename (defaults to clientName)
Whether to overwrite existing files
A promise that resolves when the file has been moved
const avatar = request.file('avatar')
await avatar.move('uploads/avatars', {
name: `${user.id}.${avatar.extname}`,
overwrite: true
})
validate()
Manually validates the file.
No return value. Check isValid property after calling.
const file = request.file('document')
file.validate()
if (!file.isValid) {
console.log(file.errors)
}
Configuration
BodyParserConfig
Configuration type for customizing body parser behavior.
type BodyParserConfig = {
allowedMethods: string[]
encoding: string
json: {
limit: string | number
strict: boolean
types: string[]
}
form: {
limit: string | number
types: string[]
}
raw: {
limit: string | number
types: string[]
}
multipart: {
autoProcess: boolean
processManually: string[]
limit: string | number
types: string[]
}
}
Example Usage
import type { HttpContext } from '@adonisjs/core/http'
export default class ContactController {
async submit({ request, response }: HttpContext) {
const data = request.only(['name', 'email', 'message'])
// Validate and process form data
await sendContactEmail(data)
return response.json({ success: true })
}
}
File Upload with Validation
import type { HttpContext } from '@adonisjs/core/http'
import app from '@adonisjs/core/services/app'
export default class UploadsController {
async upload({ request, response }: HttpContext) {
const document = request.file('document', {
size: '10mb',
extnames: ['pdf', 'doc', 'docx']
})
if (!document) {
return response.badRequest({ message: 'Document is required' })
}
if (!document.isValid) {
return response.badRequest({ errors: document.errors })
}
const fileName = `${Date.now()}.${document.extname}`
await document.move(app.makePath('uploads'), { name: fileName })
return response.json({
fileName,
size: document.size,
type: document.type
})
}
}
Multiple File Uploads
import type { HttpContext } from '@adonisjs/core/http'
export default class GalleryController {
async uploadPhotos({ request, response }: HttpContext) {
const photos = request.files('photos', {
size: '5mb',
extnames: ['jpg', 'jpeg', 'png', 'webp']
})
const uploadedFiles = []
for (const photo of photos) {
if (!photo.isValid) {
return response.badRequest({
message: 'Invalid file',
errors: photo.errors
})
}
const fileName = `${Date.now()}-${photo.clientName}`
await photo.move('uploads/gallery', { name: fileName })
uploadedFiles.push({
name: fileName,
size: photo.size
})
}
return response.json({ files: uploadedFiles })
}
}
Processing Raw Body
import type { HttpContext } from '@adonisjs/core/http'
import { Hmac } from '@adonisjs/core/encryption'
import env from '@adonisjs/core/services/env'
export default class WebhookController {
async github({ request, response }: HttpContext) {
const rawBody = request.raw()
const signature = request.header('x-hub-signature-256')
// Verify webhook signature using raw body
const hmac = new Hmac(env.get('GITHUB_WEBHOOK_SECRET'))
const isValid = hmac.verify(rawBody, signature)
if (!isValid) {
return response.unauthorized({ message: 'Invalid signature' })
}
const payload = JSON.parse(rawBody)
// Process webhook payload
return response.noContent()
}
}
Notes
- The bodyparser middleware is typically registered globally in the middleware stack
- File uploads are automatically handled for multipart/form-data requests
- Validation options can be specified per-file or globally in configuration
- Large file uploads should consider using streaming for better memory efficiency
- Raw body access is useful for webhook signature verification
- The middleware respects the Content-Type header to determine parsing strategy