As of Sails v1.0, actions2 have been the de facto way for writing controller actions.
Learn how to migrate your legacy actions to this more modern style in this Sailscasts article.
When using the actions2 style of authoring controller actions, you’d normally return an exit
. Take this simplistic controller action below as an example:
// api/controllers/admin/get-users.js
module.exports = {
friendlyName: 'Get users',
description: 'Get all users',
inputs: {
},
exits: {
success: {
description: 'Successfully retrieved all users'
},
forbidden: {
statusCode: 401,
description: 'User not permitted for this action'
}
},
fn: async function (inputs, exits) {
if (this.req.me.role != 'ADMIN') {
return exits.forbidden({
success: false,
message: 'You are not authorized for this action'
})
}
const users = await User.find({role: 'user'})
return exits.success({
success: true,
message: 'Successfully fetched users',
data: users
})
}
}
}
You can see we have two exits for this action: the success
and the forbidden
exits and we are explicitly returning them as required.
With actions2 we can simplify things a bit by returning the response to implicitly trigger the success exit or throwing a value for any other kind of exits. Let’s see this in action:
fn: async function () {
if (this.req.me.role != 'ADMIN') {
throw {
forbidden: {
success: false, message: 'You are not authorized for this action'
}
}
}
const users = await User.find({role: 'user'})
return {
success: true,
message: 'Successfully fetched users',
data: users
}
}
}
Notice we didn’t have to pass in the exits
object as an argument to the fn
function anymore and since we are not having any inputs
in this action we can safely remove the inputs
argument as well.
Also for the forbidden
exits, we are simply throwing an object with the key being the exit name we want to return.
Implicitly Sails knows you want to return JSON as the response anytime you exit
with an object so using this shorthand will save you some keystrokes as well as make your actions read more like a regular JavaScript function.
A little word on throw
For the use case above, we passed in some output data for the forbidden
exit hence the reason we call it like so:
throw {
forbidden: {
success: false, message: 'You are not authorized for this action'
}
}
However if for some reason your exit don’t have any data to be sent back, you can simply throw a string which will be the exit
name, like so:
throw 'forbidden'
How much shorter is that as to the following equivalent:
return exits.forbidden()
You can even throw a JavaScript error object to trigger the default error
exit which will make your server respond with a status code of 500
. Like so:
throw new Error('Something went wrong :)')
Conclusion
The shorthand shown in this article is an example of how Sails focuses on developer experience by providing you options to improve productivity.
Remember we use the return
keyword for a success
response or exit and we use the throw
keyword for an error response.