0
# Built-in Hooks
1
2
Sails.js includes 18+ built-in hooks that provide core framework functionality, from HTTP server management to automatic API generation. Hooks follow a standardized lifecycle and can be extended or customized to modify framework behavior.
3
4
## Hook System Architecture
5
6
### Hook Base Class
7
8
All hooks inherit from a common base class with standardized lifecycle methods:
9
10
```javascript { .api }
11
// Hook constructor factory
12
function Hook(definition: Dictionary): Hook
13
14
// Hook lifecycle methods
15
Hook.defaults(): Dictionary
16
Hook.configure(): void
17
Hook.loadModules(cb: Function): void
18
Hook.initialize(cb: Function): void
19
```
20
21
### Hook Lifecycle
22
23
Hooks execute in a specific sequence during application startup:
24
25
1. **defaults()** - Provide default configuration values
26
2. **configure()** - Normalize and validate configuration
27
3. **loadModules()** - Load modules as dictionary
28
4. **initialize()** - Prepare hook functionality
29
30
### Hook Properties
31
32
```javascript { .api }
33
hook.identity // String - Hook name/identifier
34
hook.config // Dictionary - Hook-specific configuration
35
hook.middleware // Dictionary - Hook middleware functions
36
hook.routes // Dictionary - Hook route definitions
37
hook.routes.before // Routes bound before app routes
38
hook.routes.after // Routes bound after app routes
39
```
40
41
## Core Built-in Hooks
42
43
### HTTP Hook
44
45
**Purpose**: HTTP server and middleware management
46
**Location**: `/lib/hooks/http/index.js`
47
48
```javascript { .api }
49
// Default configuration
50
{
51
port: 1337,
52
explicitHost: undefined,
53
ssl: {},
54
paths: { public: '.tmp/public' },
55
http: {
56
middleware: {
57
order: ['cookieParser', 'session', 'bodyParser', 'compress', 'faveicon', 'router', 'www', 'methodOverride']
58
},
59
cache: 1, // 1ms in development, ~1 year in production
60
trustProxy: false
61
}
62
}
63
```
64
65
**Key Features**:
66
- Express.js application integration
67
- Middleware configuration and ordering
68
- SSL certificate support
69
- Static file serving configuration
70
- Request/response object enhancement
71
72
**Configuration Example**:
73
```javascript
74
// config/http.js
75
module.exports.http = {
76
port: 3000,
77
middleware: {
78
order: ['cookieParser', 'session', 'myCustomMiddleware', 'bodyParser', 'router'],
79
myCustomMiddleware: (req, res, next) => {
80
console.log('Custom middleware executed');
81
next();
82
}
83
},
84
trustProxy: true
85
};
86
```
87
88
### Blueprints Hook
89
90
**Purpose**: Automatic REST API generation for models
91
**Location**: `/lib/hooks/blueprints/index.js`
92
93
```javascript { .api }
94
// Default configuration
95
{
96
blueprints: {
97
actions: false, // Action shadow routes
98
shortcuts: true, // GET-only CRUD shortcuts
99
rest: true, // RESTful routes
100
prefix: '', // Route prefix
101
restPrefix: '', // REST-specific prefix
102
pluralize: false, // Pluralize model names in URLs
103
autoWatch: true // Auto-subscribe to model changes
104
}
105
}
106
```
107
108
**Generated Actions**:
109
- `create` - Create new record
110
- `find` - Find records with filtering
111
- `findOne` - Find single record by ID
112
- `update` - Update existing record
113
- `destroy` - Delete record
114
- `populate` - Populate associations
115
- `add` - Add to collection association
116
- `remove` - Remove from collection association
117
- `replace` - Replace collection association
118
119
**Route Generation Examples**:
120
```javascript
121
// For User model, generates:
122
123
// RESTful routes (rest: true)
124
'GET /user' → UserController.find
125
'POST /user' → UserController.create
126
'GET /user/:id' → UserController.findOne
127
'PUT /user/:id' → UserController.update
128
'DELETE /user/:id' → UserController.destroy
129
130
// Shortcut routes (shortcuts: true)
131
'GET /user/find' → UserController.find
132
'GET /user/create' → UserController.create
133
'GET /user/update/:id' → UserController.update
134
'GET /user/destroy/:id' → UserController.destroy
135
136
// Action routes (actions: true)
137
'GET /user/customAction' → UserController.customAction
138
```
139
140
### Security Hook
141
142
**Purpose**: CORS and CSRF protection
143
**Location**: `/lib/hooks/security/index.js`
144
145
**Sub-hooks**:
146
- **CORS**: Cross-Origin Resource Sharing protection
147
- **CSRF**: Cross-Site Request Forgery protection
148
149
**Configuration Example**:
150
```javascript
151
// config/security.js
152
module.exports.security = {
153
cors: {
154
allRoutes: true,
155
allowOrigins: ['http://localhost:3000', 'https://myapp.com'],
156
allowCredentials: false,
157
allowRequestMethods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
158
allowRequestHeaders: 'content-type'
159
},
160
161
csrf: {
162
grantTokenViaAjax: true,
163
origin: 'https://myapp.com'
164
}
165
};
166
```
167
168
### Views Hook
169
170
**Purpose**: View engine configuration and rendering
171
**Location**: `/lib/hooks/views/index.js`
172
173
**Key Features**:
174
- Multiple template engine support (EJS, Handlebars, Jade, etc.)
175
- View caching in production
176
- Layout and partial support
177
- Custom view helpers
178
179
**Configuration Example**:
180
```javascript
181
// config/views.js
182
module.exports.views = {
183
engine: 'ejs',
184
layout: 'layouts/layout',
185
extension: 'ejs',
186
187
// View locals available to all templates
188
locals: {
189
siteName: 'My Sails App',
190
title: 'Welcome'
191
}
192
};
193
```
194
195
### Session Hook
196
197
**Purpose**: Session management and storage
198
**Location**: `/lib/hooks/session/index.js`
199
200
**Key Features**:
201
- Multiple session store support (memory, Redis, MongoDB)
202
- Session configuration and middleware
203
- Cookie settings and security
204
205
**Configuration Example**:
206
```javascript
207
// config/session.js
208
module.exports.session = {
209
secret: 'your-session-secret',
210
adapter: 'redis',
211
host: 'localhost',
212
port: 6379,
213
db: 0,
214
215
cookie: {
216
secure: false, // Set true for HTTPS
217
maxAge: 24 * 60 * 60 * 1000 // 24 hours
218
}
219
};
220
```
221
222
### Logger Hook
223
224
**Purpose**: Logging system setup
225
**Location**: `/lib/hooks/logger/index.js`
226
227
```javascript { .api }
228
// Default configuration
229
{
230
log: {
231
level: 'info' // silly, verbose, info, warn, error, silent
232
}
233
}
234
235
// Available log methods
236
sails.log.error() // Error level
237
sails.log.warn() // Warning level
238
sails.log.info() // Info level (default)
239
sails.log.verbose() // Verbose level
240
sails.log.silly() // Debug level
241
sails.log.ship() // ASCII art ship (special method)
242
```
243
244
**Features**:
245
- CaptainsLog integration
246
- Configurable log levels
247
- Color-coded console output
248
- ASCII art ship display
249
250
### Policies Hook
251
252
**Purpose**: Policy enforcement middleware
253
**Location**: `/lib/hooks/policies/index.js`
254
255
**Key Features**:
256
- Policy auto-loading from `api/policies/`
257
- Policy mapping to controllers and actions
258
- Middleware chain execution
259
260
**Configuration Example**:
261
```javascript
262
// config/policies.js
263
module.exports.policies = {
264
'*': 'isLoggedIn', // Apply to all controllers
265
266
UserController: {
267
'*': 'isLoggedIn', // All actions
268
'create': ['isLoggedIn', 'isAdmin'], // Multiple policies
269
'find': true // Open access
270
},
271
272
'user/profile': 'isOwnerOrAdmin' // Standalone action policy
273
};
274
```
275
276
### Services Hook
277
278
**Purpose**: Service auto-loading and global exposure
279
**Location**: `/lib/hooks/services/index.js`
280
281
**Key Features**:
282
- Automatic service discovery in `api/services/`
283
- Global service exposure
284
- Service dependency injection
285
286
**Service Example**:
287
```javascript
288
// api/services/EmailService.js
289
module.exports = {
290
sendWelcomeEmail: async function(userEmail, userName) {
291
// Email sending logic
292
console.log(`Sending welcome email to ${userEmail}`);
293
return { sent: true };
294
},
295
296
sendPasswordReset: async function(userEmail, resetToken) {
297
// Password reset email logic
298
return { sent: true, token: resetToken };
299
}
300
};
301
302
// Usage anywhere in the app
303
await EmailService.sendWelcomeEmail('user@example.com', 'John');
304
```
305
306
### Helpers Hook
307
308
**Purpose**: Helper function loading and management
309
**Location**: `/lib/hooks/helpers/index.js`
310
311
**Key Features**:
312
- Machine-based helper definitions
313
- Helper auto-loading from `api/helpers/`
314
- Input validation and output formatting
315
316
**Helper Example**:
317
```javascript
318
// api/helpers/format-date.js
319
module.exports = {
320
friendlyName: 'Format date',
321
description: 'Format a date for display',
322
323
inputs: {
324
date: {
325
type: 'ref',
326
required: true
327
},
328
format: {
329
type: 'string',
330
defaultsTo: 'YYYY-MM-DD'
331
}
332
},
333
334
fn: async function(inputs) {
335
const moment = require('moment');
336
return moment(inputs.date).format(inputs.format);
337
}
338
};
339
340
// Usage
341
const formatted = await sails.helpers.formatDate(new Date(), 'MMM DD, YYYY');
342
```
343
344
### Internationalization Hook (i18n)
345
346
**Purpose**: Internationalization and localization support
347
**Location**: `/lib/hooks/i18n/index.js`
348
349
**Key Features**:
350
- Multiple language support
351
- Locale switching and detection
352
- Template integration
353
354
**Configuration Example**:
355
```javascript
356
// config/i18n.js
357
module.exports.i18n = {
358
locales: ['en', 'es', 'fr'],
359
defaultLocale: 'en',
360
directory: './config/locales',
361
362
// Request locale detection
363
requestLocaleProperty: 'locale',
364
queryParameter: 'lang'
365
};
366
```
367
368
## Infrastructure Hooks
369
370
### User Config Hook
371
372
**Purpose**: User configuration loading
373
**Location**: `/lib/hooks/userconfig/index.js`
374
375
**Features**:
376
- Configuration file processing
377
- Environment-specific config loading
378
- Config validation and normalization
379
380
### User Hooks Hook
381
382
**Purpose**: Custom user hook loading
383
**Location**: `/lib/hooks/userhooks/index.js`
384
385
**Features**:
386
- Third-party hook integration
387
- Custom hook discovery in `api/hooks/`
388
- Hook dependency resolution
389
390
### Module Loader Hook
391
392
**Purpose**: Dynamic module loading infrastructure
393
**Location**: `/lib/hooks/moduleloader/index.js`
394
395
**Features**:
396
- Module discovery patterns
397
- Dynamic require resolution
398
- Circular dependency handling
399
400
### Request Hook
401
402
**Purpose**: Request object enhancement
403
**Location**: `/lib/hooks/request/index.js`
404
405
**Features**:
406
- Request parameter parsing
407
- Input validation helpers
408
- Request context enhancement
409
410
### Responses Hook
411
412
**Purpose**: Response method injection
413
**Location**: `/lib/hooks/responses/index.js`
414
415
**Features**:
416
- Custom response methods (res.ok, res.badRequest, etc.)
417
- Response auto-loading from `api/responses/`
418
- Status code and header management
419
420
**Default Response Methods**:
421
```javascript { .api }
422
res.ok() // 200 - Success
423
res.created() // 201 - Created
424
res.badRequest() // 400 - Bad Request
425
res.unauthorized() // 401 - Unauthorized
426
res.forbidden() // 403 - Forbidden
427
res.notFound() // 404 - Not Found
428
res.serverError() // 500 - Internal Server Error
429
```
430
431
### Pub/Sub Hook
432
433
**Purpose**: Publish/Subscribe functionality
434
**Location**: `/lib/hooks/pubsub/index.js`
435
436
**Features**:
437
- Real-time communication support
438
- Model subscription management
439
- WebSocket integration
440
441
**Usage Example**:
442
```javascript
443
// Subscribe to model updates
444
User.subscribe(req, [userId]);
445
446
// Publish model changes
447
User.publishUpdate(userId, { status: 'active' });
448
449
// Room-based messaging
450
sails.sockets.join(req, 'chatroom1');
451
sails.sockets.broadcast('chatroom1', { message: 'Hello!' });
452
```
453
454
## Custom Hook Development
455
456
### Creating Custom Hooks
457
458
Custom hooks are created in the `api/hooks/` directory:
459
460
```javascript
461
// api/hooks/my-hook/index.js
462
module.exports = function myHook(sails) {
463
return {
464
// Hook configuration defaults
465
defaults: {
466
myHook: {
467
enabled: true,
468
customSetting: 'default-value'
469
}
470
},
471
472
// Configuration normalization
473
configure: function() {
474
// Validate and normalize config
475
if (!sails.config.myHook.enabled) {
476
console.log('MyHook is disabled');
477
}
478
},
479
480
// Module loading
481
loadModules: function(cb) {
482
// Load additional modules if needed
483
return cb();
484
},
485
486
// Hook initialization
487
initialize: function(cb) {
488
console.log('MyHook initialized');
489
490
// Add custom functionality to sails
491
sails.myCustomMethod = function() {
492
return 'Custom functionality';
493
};
494
495
return cb();
496
},
497
498
// Custom hook routes
499
routes: {
500
before: {
501
'GET /hook-test': function(req, res) {
502
return res.json({ hook: 'MyHook responding' });
503
}
504
}
505
}
506
};
507
};
508
```
509
510
### Hook Installation
511
512
Custom hooks can be installed via npm:
513
514
```bash
515
npm install sails-hook-my-custom-hook
516
```
517
518
Or developed locally in `api/hooks/my-hook/`.
519
520
### Hook Configuration
521
522
Hook behavior can be controlled through configuration:
523
524
```javascript
525
// config/my-hook.js
526
module.exports.myHook = {
527
enabled: true,
528
customSetting: 'production-value',
529
530
// Environment-specific settings
531
environments: {
532
development: {
533
enabled: true,
534
debugMode: true
535
},
536
production: {
537
enabled: true,
538
debugMode: false
539
}
540
}
541
};
542
```
543
544
## Hook Utilities
545
546
### Environment Filtering
547
548
Hooks can be configured to load only in specific environments:
549
550
```javascript
551
module.exports = function(sails) {
552
return {
553
// Only load in development
554
configure: function() {
555
if (sails.config.environment !== 'development') {
556
return;
557
}
558
}
559
};
560
};
561
```
562
563
### Hook Dependencies
564
565
Hooks can specify dependencies on other hooks:
566
567
```javascript
568
module.exports = function(sails) {
569
return {
570
dependencies: ['orm', 'http'],
571
572
initialize: function(cb) {
573
// This hook will only initialize after orm and http hooks
574
return cb();
575
}
576
};
577
};
578
```
579
580
The Sails.js hook system provides a powerful and flexible architecture for extending framework functionality, with comprehensive built-in hooks covering all core web application needs and extensive customization capabilities.