0
# HTTP Routing
1
2
Sails.js provides a powerful and flexible routing system that supports both programmatic route definition and configuration-based routing. The router handles HTTP requests and routes them to appropriate actions, with support for RESTful conventions, middleware chaining, and automatic blueprint generation.
3
4
## Core Routing Methods
5
6
### HTTP Method Shortcuts
7
8
Sails provides convenient methods for binding routes to specific HTTP methods:
9
10
```javascript { .api }
11
sails.get(path: String, action: String|Function): Sails
12
sails.post(path: String, action: String|Function): Sails
13
sails.put(path: String, action: String|Function): Sails
14
sails.delete(path: String, action: String|Function): Sails
15
sails.del(path: String, action: String|Function): Sails // Alias for delete
16
sails.all(path: String, action: String|Function): Sails
17
```
18
19
**Parameters**:
20
- `path` (String) - Route pattern (e.g., '/users/:id', '/api/v1/posts')
21
- `action` (String|Function) - Target action or controller method
22
23
**Returns**: `Sails` - The Sails instance for method chaining
24
25
**Examples**:
26
```javascript
27
const sails = require('sails');
28
29
// GET route with function action
30
sails.get('/hello', (req, res) => {
31
return res.json({ message: 'Hello World!' });
32
});
33
34
// POST route with controller action reference
35
sails.post('/users', 'UserController.create');
36
37
// PUT route with standalone action
38
sails.put('/users/:id', 'user/update');
39
40
// DELETE route (both syntaxes work)
41
sails.delete('/users/:id', 'UserController.destroy');
42
sails.del('/users/:id', 'UserController.destroy');
43
44
// Catch-all route for any HTTP method
45
sails.all('/api/*', 'ApiController.handleRequest');
46
47
// Method chaining
48
sails
49
.get('/posts', 'PostController.find')
50
.post('/posts', 'PostController.create')
51
.put('/posts/:id', 'PostController.update')
52
.delete('/posts/:id', 'PostController.destroy');
53
```
54
55
## Router Instance
56
57
The Sails router is available at `sails.router` and provides lower-level routing functionality:
58
59
### bind()
60
61
Bind new route(s) with advanced options:
62
63
```javascript { .api }
64
sails.router.bind(path: String|RegExp, bindTo: String|Object|Array|Function, verb?: String, routeOptions?: Dictionary): void
65
```
66
67
**Parameters**:
68
- `path` (String|RegExp) - Route pattern or regular expression
69
- `bindTo` (String|Object|Array|Function) - Target action, middleware, or handler
70
- `verb` (String, optional) - HTTP method (default: all methods)
71
- `routeOptions` (Dictionary, optional) - Additional route configuration
72
73
**Examples**:
74
```javascript
75
// Basic route binding
76
sails.router.bind('/api/users', 'UserController.find', 'GET');
77
78
// Route with middleware chain
79
sails.router.bind('/admin/*', ['isAuthenticated', 'isAdmin', 'AdminController.dashboard']);
80
81
// Route with options
82
sails.router.bind('/upload', 'FileController.upload', 'POST', {
83
skipAssets: true,
84
cors: { origin: 'https://myapp.com' }
85
});
86
87
// RegExp route
88
sails.router.bind(/^\/api\/v(\d+)\/users$/, (req, res) => {
89
const version = req.params[0];
90
return res.json({ version, users: [] });
91
});
92
```
93
94
### Route Management
95
96
```javascript { .api }
97
// Remove existing route
98
sails.router.unbind(routeToRemove: Object): void
99
100
// Remove all routes
101
sails.router.reset(): void
102
103
// Rebuild all routes
104
sails.router.flush(routes?: Dictionary): void
105
```
106
107
**Examples**:
108
```javascript
109
// Reset all routes
110
sails.router.reset();
111
112
// Flush and rebuild with new route configuration
113
sails.router.flush({
114
'GET /users': 'UserController.find',
115
'POST /users': 'UserController.create'
116
});
117
```
118
119
## Route Patterns
120
121
### Parameter Extraction
122
123
Sails supports Express-style route parameters:
124
125
```javascript
126
// Named parameters
127
sails.get('/users/:id', (req, res) => {
128
const userId = req.params.id;
129
return res.json({ userId });
130
});
131
132
// Multiple parameters
133
sails.get('/users/:userId/posts/:postId', (req, res) => {
134
const { userId, postId } = req.params;
135
return res.json({ userId, postId });
136
});
137
138
// Optional parameters
139
sails.get('/posts/:id?', (req, res) => {
140
const id = req.params.id || 'all';
141
return res.json({ posts: id });
142
});
143
144
// Wildcard routes
145
sails.get('/files/*', (req, res) => {
146
const filePath = req.params[0];
147
return res.json({ file: filePath });
148
});
149
```
150
151
### Query Parameters
152
153
Access query parameters through `req.query`:
154
155
```javascript
156
sails.get('/search', (req, res) => {
157
const { q, limit, page } = req.query;
158
return res.json({
159
query: q,
160
limit: parseInt(limit) || 10,
161
page: parseInt(page) || 1
162
});
163
});
164
165
// GET /search?q=sails&limit=20&page=2
166
```
167
168
## Action Targets
169
170
Routes can target different types of actions:
171
172
### Controller Methods
173
```javascript
174
// Traditional controller method syntax
175
sails.get('/users', 'UserController.find');
176
sails.post('/users', 'UserController.create');
177
178
// Object-style target
179
sails.router.bind('/users', {
180
controller: 'UserController',
181
action: 'find'
182
}, 'GET');
183
```
184
185
### Standalone Actions
186
```javascript
187
// Standalone action identity
188
sails.get('/login', 'entrance/login');
189
sails.post('/logout', 'account/logout');
190
191
// Action object target
192
sails.router.bind('/profile', {
193
action: 'account/view-profile'
194
});
195
```
196
197
### Function Handlers
198
```javascript
199
// Direct function
200
sails.get('/health', (req, res) => {
201
return res.json({ status: 'ok', timestamp: Date.now() });
202
});
203
204
// Async function
205
sails.get('/async-route', async (req, res) => {
206
const data = await someAsyncOperation();
207
return res.json(data);
208
});
209
```
210
211
### Middleware Chains
212
```javascript
213
// Multiple middleware functions
214
sails.get('/protected', [
215
'isAuthenticated',
216
'hasPermission',
217
'UserController.dashboard'
218
]);
219
220
// Mixed middleware and functions
221
sails.post('/upload', [
222
(req, res, next) => {
223
console.log('Upload started');
224
next();
225
},
226
'isAuthenticated',
227
'FileController.upload'
228
]);
229
```
230
231
## Route Discovery
232
233
### getRouteFor()
234
235
Find route information for a given target:
236
237
```javascript { .api }
238
sails.getRouteFor(target: String|Dictionary): {url: String, method: String}
239
```
240
241
**Parameters**:
242
- `target` (String|Dictionary) - Route target to search for
243
244
**Returns**: Object with `url` and `method` properties
245
246
**Throws**:
247
- `E_NOT_FOUND` - Route not found
248
- `E_USAGE` - Invalid input
249
250
**Examples**:
251
```javascript
252
// Find route by controller method
253
const route = sails.getRouteFor('UserController.find');
254
console.log(route); // { url: '/users', method: 'get' }
255
256
// Find route by action identity
257
const loginRoute = sails.getRouteFor('entrance/login');
258
console.log(loginRoute); // { url: '/login', method: 'get' }
259
260
// Find route by object target
261
const route2 = sails.getRouteFor({
262
controller: 'User',
263
action: 'create'
264
});
265
console.log(route2); // { url: '/users', method: 'post' }
266
```
267
268
### getUrlFor()
269
270
Get URL pattern for a route target:
271
272
```javascript { .api }
273
sails.getUrlFor(target: String|Dictionary): String
274
```
275
276
**Parameters**:
277
- `target` (String|Dictionary) - Route target to search for
278
279
**Returns**: `String` - URL pattern
280
281
**Examples**:
282
```javascript
283
// Get URL for controller method
284
const url = sails.getUrlFor('UserController.show');
285
console.log(url); // '/users/:id'
286
287
// Get URL for action
288
const loginUrl = sails.getUrlFor('entrance/login');
289
console.log(loginUrl); // '/login'
290
```
291
292
## Virtual Request Routing
293
294
### route()
295
296
Route virtual requests (non-HTTP) through the router:
297
298
```javascript { .api }
299
sails.router.route(req: Object, res: Object): void
300
```
301
302
**Parameters**:
303
- `req` - Request object (can be partial)
304
- `res` - Response object (can be partial)
305
306
**Example**:
307
```javascript
308
// Create virtual request/response
309
const mockReq = {
310
method: 'GET',
311
url: '/api/users',
312
headers: {}
313
};
314
315
const mockRes = {
316
json: (data) => console.log('Response:', data),
317
status: (code) => mockRes
318
};
319
320
// Route the virtual request
321
sails.router.route(mockReq, mockRes);
322
```
323
324
## Route Analysis Utilities
325
326
### getActionIdentityForTarget()
327
328
Extract action identity from route targets:
329
330
```javascript { .api }
331
sails.router.getActionIdentityForTarget(target: String|Dictionary): String
332
```
333
334
**Examples**:
335
```javascript
336
// Controller method to action identity
337
const identity1 = sails.router.getActionIdentityForTarget('UserController.create');
338
console.log(identity1); // 'user/create'
339
340
// Object target to action identity
341
const identity2 = sails.router.getActionIdentityForTarget({
342
controller: 'User',
343
action: 'show'
344
});
345
console.log(identity2); // 'user/show'
346
347
// Direct action identity (pass-through)
348
const identity3 = sails.router.getActionIdentityForTarget('account/login');
349
console.log(identity3); // 'account/login'
350
```
351
352
### getSortedRouteAddresses()
353
354
Get sorted list of all route addresses:
355
356
```javascript { .api }
357
sails.router.getSortedRouteAddresses(): Array<String>
358
```
359
360
**Returns**: `Array<String>` - Cloned and sorted array of route addresses
361
362
**Example**:
363
```javascript
364
const addresses = sails.router.getSortedRouteAddresses();
365
console.log(addresses);
366
// ['GET /api/users', 'POST /api/users', 'GET /api/users/:id', ...]
367
```
368
369
## Configuration-Based Routing
370
371
Routes can also be defined in `config/routes.js`:
372
373
```javascript
374
// config/routes.js
375
module.exports.routes = {
376
// Basic routes
377
'GET /': 'PageController.home',
378
'POST /login': 'AuthController.login',
379
380
// RESTful routes
381
'GET /api/users': 'UserController.find',
382
'POST /api/users': 'UserController.create',
383
'GET /api/users/:id': 'UserController.findOne',
384
'PUT /api/users/:id': 'UserController.update',
385
'DELETE /api/users/:id': 'UserController.destroy',
386
387
// Wildcard routes
388
'GET /admin/*': 'AdminController.route',
389
390
// Route with middleware
391
'POST /upload': ['isAuthenticated', 'FileController.upload']
392
};
393
```
394
395
## Route Properties and Options
396
397
### Route Options
398
399
Routes support various configuration options:
400
401
```javascript
402
sails.router.bind('/api/secure', 'SecureController.data', 'GET', {
403
// Skip asset pipeline for this route
404
skipAssets: true,
405
406
// CORS configuration
407
cors: {
408
origin: 'https://myapp.com',
409
credentials: true
410
},
411
412
// Rate limiting (if configured)
413
rateLimit: {
414
max: 100,
415
windowMs: 60000
416
}
417
});
418
```
419
420
### Router Properties
421
422
The router instance exposes several properties:
423
424
```javascript { .api }
425
sails.router.explicitRoutes // Reference to sails.config.routes
426
sails.router.log // Reference to sails logger
427
sails.router._privateRouter // Internal Express-like router
428
```
429
430
## Error Handling
431
432
Route errors are automatically handled by Sails:
433
434
```javascript
435
// 404 handling - automatic for unmatched routes
436
sails.on('router:request:404', (req, res) => {
437
return res.status(404).json({ error: 'Not found' });
438
});
439
440
// 500 handling - automatic for route errors
441
sails.on('router:request:500', (req, res, err) => {
442
console.error('Route error:', err);
443
return res.status(500).json({ error: 'Server error' });
444
});
445
```
446
447
The Sails routing system provides comprehensive functionality for handling HTTP requests, from simple route definitions to complex middleware chains and virtual request routing, with full support for RESTful conventions and flexible configuration options.