Blueprint actions (not to be confused with implicit blueprint "action" routes) are generic actions designed to work with your models. Think of them as the default behavior for your application. For instance, if you have a User.js
model then find
, create
, update
, destroy
, populate
, add
and remove
actions exist implicitly, without you having to write them.
By default, the blueprint RESTful routes and shortcut routes are bound to their corresponding blueprint actions. However, any blueprint action can be overridden for a particular controller by creating a custom action in that controller file (e.g. ParrotController.find
).
The current version of Sails ships with the following blueprint actions:
Most blueprint actions have realtime features that take effect if your app has WebSockets enabled. For example, if the find blueprint action receives a request from a socket client, it will subscribe that socket to future notifications. Then, any time records are changed using blueprint actions like update, Sails will publish certain notifications.
The best way to understand the behavior of a particular blueprint action is to read its reference page (or see the list above). But if you're looking for more of a birds-eye view of how realtime features work in Sails's blueprint API, see Concepts > Realtime. (If you're OK with some details being out of date, you might even want to check out the original "Intro to Sails.js" video from 2013.)
For a more advanced breakdown of all notifications published by blueprint actions in Sails, see:
You may also override any of the blueprint actions for a controller by defining a custom action with the same name.
// api/controllers/user/UserController.js
module.exports = {
/**
* A custom action that overrides the built-in "findOne" blueprint action.
* As a dummy example of customization, imagine we were working on something in our app
* that demanded we tweak the format of the response data, and that we only populate two
* associations: "company" and "friends".
*/
findOne: function (req, res) {
sails.log.debug('Running custom `findOne` action. (Will look up user #'+req.param(\'id\')...');
User.findOne({ id: req.param('id') }).omit(['password'])
.populate('company', { select: ['profileImageUrl'] })
.populate('top8', { omit: ['password'] })
.exec(function(err, userRecord) {
if (err) {
switch (err.name) {
case 'UsageError': return res.badRequest(err);
default: return res.serverError(err);
}
}
if (!userRecord) { return res.notFound(); }
if (req.isSocket) {
User.subscribe(req, [user.id]);
}
return res.ok({
model: 'user',
luckyCoolNumber: Math.ceil(10*Math.random()),
record: userRecord
});
});
}
}
Alternatively, we could have created this as a standalone action at
api/controllers/user/findone.js
or used actions2.