The request context: request and response
Every route handler and controller method receives an HttpContext object — the context of the current HTTP request. It contains everything you need to respond: request data, the response object, address parameters, the session, the current user.
Context fields
| Field | What it is |
|---|---|
request | The incoming request: address, headers, form data |
response | The response: status, headers, redirects, JSON |
params | Parameters from the route address |
view | Edge templates (in the Web kit) |
session | The user session |
auth | Login and the current user (once auth is configured) |
Usually you destructure only the fields you need from the context.
Reading the request
The input method takes one field from the query string or the form body:
// app/controllers/posts_controller.ts
import type { HttpContext } from '@adonisjs/core/http'
export default class PostsController {
async index({ request }: HttpContext) {
const search = request.input('q', '')
return `Search: ${search}`
}
}Open /posts?q=adonis — you see "Search: adonis". The second argument of input is the default value when the field is missing.
Other useful request methods:
| Method | What it returns |
|---|---|
request.all() | All query string and body fields together |
request.only(['title', 'body']) | Only the listed fields |
request.qs() | Only the query string as an object |
request.header('user-agent') | A header value |
request.method() | The method: GET, POST |
request.url() | The address without the domain |
request.ip() | The visitor's IP address |
Sending a response
A simple response can just be returned from the method. When you need a status, a header or a redirect, use response:
// app/controllers/posts_controller.ts
async store({ request, response }: HttpContext) {
const title = request.input('title')
return response.status(201).json({ created: true, title })
}On POST /posts with a title field the client gets status 201 and JSON with the post title.
Redirects
// app/controllers/posts_controller.ts
async old({ response }: HttpContext) {
return response.redirect('/posts')
}
async back({ response }: HttpContext) {
return response.redirect().back()
}The first method sends the browser to /posts, the second back to the page the request came from. For named routes there is response.redirect().toRoute('posts.index').
Ready-made error responses
// app/controllers/posts_controller.ts
async show({ params, response }: HttpContext) {
if (params.id === '0') {
return response.notFound('Post not found')
}
return `Post ${params.id}`
}notFound sets status 404. There are others: badRequest (400), unauthorized (401), forbidden (403).
Common mistake
If you do not return the result of response.redirect(...) or response.json(...), the response is still sent, but the method keeps running and may overwrite it. Write return response.redirect('/posts') so the method ends right there.