Skip to main content
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

application/json
automatic
Parses JSON payloads and makes them available via request.body()
application/x-www-form-urlencoded
automatic
Parses URL-encoded form data and makes it available via request.body()
multipart/form-data
automatic
Parses multipart form data including file uploads. Files are available via request.file() and other fields via request.body()
text/plain
automatic
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.
return
object
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.
key
string
required
The field name of the uploaded file
options
object
Optional validation options
size
string | number
Maximum file size (e.g., ‘2mb’, 2048)
extnames
string[]
Allowed file extensions
return
MultipartFile | null
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.
key
string
required
The field name of the uploaded files (for array uploads)
options
object
Optional validation options (same as request.file())
return
MultipartFile[]
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.
return
object
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.
return
string
The raw request body
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

fieldName
string
The field name used in the form
clientName
string
The original filename provided by the client
size
number
The file size in bytes
extname
string
The file extension
type
string
The MIME type of the file
subtype
string
The MIME subtype
isValid
boolean
Whether the file passed validation
errors
object[]
Array of validation errors
validated
boolean
Whether validation has been performed

Methods

move()

Moves the uploaded file to a permanent location.
location
string
required
The directory path where the file should be moved
options
object
Optional configuration
name
string
Custom filename (defaults to clientName)
overwrite
boolean
default:"false"
Whether to overwrite existing files
return
Promise<void>
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.
return
void
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

Simple Form Submission

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