You are viewing the legacy version of AdonisJS. Visit for newer docs. This version will receive security patches until the end of 2021.


AdonisJs is primarily a web framework which deals over HTTP protocol. In this guide, we learn how AdonisJs handles the HTTP requests through registered routes and middleware.

Request flow

Below is a flow chart on how HTTP request flow works
Adonis Http Request Flow grqcfd

  1. The server level middleware stack includes a middleware to serve static resources from the public directory. You should only add server level middleware when they can override the URL’s registered by routes.

  2. If a request is not intercepted by server level middleware, then AdonisJs looks for a registered route, if a route is found, the global, named middleware and route action is executed.

  3. Otherwise, a 404 exception is thrown.

Http context

Since Node.js handles HTTP requests concurrently, each request needs to be identified and managed uniquely. AdonisJs creates a request Context which is a class instance containing all the request related data.

So when you bind a handler to the Route, that handler is executed for each request matching that URL and receives a unique context instance.

Route.get('/', (ctx) => {
  // ctx.request
  // ctx.response

Alternatively, you can make use of ES6 destructuring.

Route.get('/', ({ request, response }) => {
  // request
  // response

The best part of context object is that you can pull a lot more objects from it. For example: auth, view etc.

Public directory

The public directory in the root of your application is registered to serve static resources like css, images and fonts, etc.

All files inside this directory are available publicly without any authentication or restrictions.


There are a couple of ways to make use of views, and it is essential to understand the difference between them. One way is to import the View provider, the other is to use HTTP specific view instance.

Import manually

const View = use('View')

// render view
const html = View.render('home', {})

Http view instance

Route.get('/', async ({ view }) => {
  return view.render('home')

The fundamental difference is that the HTTP view instance contains a bunch of requests specific locals like request, the authenticated user, etc.

So always make sure to use the HTTP view instance during request lifecycle.