Response

This guide gives an outline on how to make use of the HTTP Response object to make the response.

The Node.js raw res object can be accessed as response.response.

AdonisJs passes the current HTTP response object as part of the context which is sent to all route handlers and middleware.

Route.get('/', ({ response }) => {
  response.send('hello world')
})

Basic example

Let’s see how to send an array of users back as JSON from the route.

Route.get('/', async ({ response }) => {
  const users = await User.all()
  response.send(users)
})

Also, you can use response.json method as an alias to response.send

Making response

As of 4.0, you can also return values from the route closure or controller method, instead of using dedicated response methods.

The following is equivalent to response.send or response.json but feels more natural with a return statement.

Route.get('/', async () => {
  return await User.all()
})

No callbacks please

Since the request/response lifecycle allows you to return values and calling dedicated methods, it discourages the usage of callbacks entirely.

Which means the following will not work.

Route.get('/', async ({ response }) => {
  fs.readFile('somefile', (error, contents) => {
    response.send(contents)
  })
})

The reason why above code is not going to work, is that as soon the route handler is executed, AdonisJs ends the response, and your callback gets executed later, resulting in an error.

It may sound scary, but it is done in favor of having a clean codebase, instead of sprinkling mixed API everywhere.

Promisfying callbacks

What you can do instead is promisify the callback and use it with await.

const Helpers = use('Helpers')
const fs = use('fs')
const readFile = Helpers.promisify(fs.readFile)

Route.get('/', async ({ response }) => {
  return await readFile('somefile')
})

See how cleaner the code is now. Javascript has a rich eco-system, and it is 100% possible to write code without callbacks just by promisfying them, and as a community, we want to encourage it.

I need callbacks

Even if you think using callbacks are great, we got a way for you to use them. Simply instruct response object not to end implicitly.

Route.get('/', async ({ response }) => {
  response.implicitEnd = false

  fs.readFile('somefile', (error, contents) => {
    response.send(contents)
  })
})

Headers

Following is the list of methods to set/remove headers.

header

Set’s header on the response

response.header('Content-type', 'application/json')

safeHeader

Only set the header if it does not exist.

response.safeHeader('Content-type', 'application/json')

removeHeader

Remove existing header

response.removeHeader('Content-type')

type

Set Content-type header.

response.type('application/json')

Cookies

Also, you can set/remove cookies by calling one of the following methods

response.cookie('cartTotal', 20)

clearCookie

Remove existing cookie by setting the expiry in the past.

response.clearCookie('cartTotal')

plainCookie

Since all cookies are encrypted and signed, it is not possible to read them from frontend Javascript code. In that case, may want to set a plain cookie instead.

// not signed or encrypted
response.plainCookie('cartTotal', 20)

Redirects

Use one of the following methods to redirect requests to a different URL.

redirect(url, sendParams = false, status = 302)

Redirect request to a different url, by default it will set the status as 302.

response.redirect('/url')

// or
response.redirect('/url', false, 301)

Also, you can send current request params to the other request as well by setting true as the 2nd param.

response.redirect('/url', true)

route(route, data, domain, sendParams = false, status = 302)

Redirect to a route. This method builds the URL automatically from the route name or controller method.

Defining route
Route
  .get('users/:id', 'UserController.show')
  .as('profile')
Redirect
response.route('profile', { id: 1 })

Also, you can pass the controller method.

Redirect
response.route('UserController.show', { id: 1 })

Since AdonisJs allows registering routes for multiple domains, you can instruct this method to build the URL for a specific domain.

response.route('posts', { id: 1 }, 'blog.adonisjs.com')

Attachments

The response object makes it super easy to stream files from your server to the client.

download(filePath)

Stream the file to the client. This method does not force the client to download the file as an attachment. For example, Browsers may choose to display the file in a new window.

response.download(Helpers.tmpPath('uploads/avatar.jpg'))

attachment(filePath, name, disposition)

Force download the file

response.attachment(
  Helpers.tmpPath('uploads/avatar.jpg')
)

With a custom name

response.attachment(
  Helpers.tmpPath('uploads/avatar.jpg'),
  'myAvatar.jpg'
)

Extending Response

It is also possible to extend the Response prototype by adding your own methods, known as macros.

Application specific

If your macros are specific to your application only, you can add the macro inside start/hooks.js file after the providers have been booted.

const { hooks } = require('@adonisjs/ignitor')

hooks.after.providersBooted(() => {
  const Response = use('Adonis/Src/Response')

  Response.macro('sendStatus', function (status) {
    this.status(status).send(status)
  })
})

Via Provider

If you are writing a module/addon for AdonisJs, you can add a macro inside the boot method of your service provider.

const { ServiceProvider } = require('@adonisjs/fold')

class MyServiceProvider extends ServiceProvider {
  boot () {
    const Response = use('Adonis/Src/Response')

    Response.macro('sendStatus', function (status) {
      this.status(status).send(status)
    })
  }
}