API-driven framework for building realtime apps, using MVC conventions (based on Express and Socket.io)
—
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.
Sails provides convenient methods for binding routes to specific HTTP methods:
sails.get(path: String, action: String|Function): Sails
sails.post(path: String, action: String|Function): Sails
sails.put(path: String, action: String|Function): Sails
sails.delete(path: String, action: String|Function): Sails
sails.del(path: String, action: String|Function): Sails // Alias for delete
sails.all(path: String, action: String|Function): SailsParameters:
path (String) - Route pattern (e.g., '/users/:id', '/api/v1/posts')action (String|Function) - Target action or controller methodReturns: Sails - The Sails instance for method chaining
Examples:
const sails = require('sails');
// GET route with function action
sails.get('/hello', (req, res) => {
return res.json({ message: 'Hello World!' });
});
// POST route with controller action reference
sails.post('/users', 'UserController.create');
// PUT route with standalone action
sails.put('/users/:id', 'user/update');
// DELETE route (both syntaxes work)
sails.delete('/users/:id', 'UserController.destroy');
sails.del('/users/:id', 'UserController.destroy');
// Catch-all route for any HTTP method
sails.all('/api/*', 'ApiController.handleRequest');
// Method chaining
sails
.get('/posts', 'PostController.find')
.post('/posts', 'PostController.create')
.put('/posts/:id', 'PostController.update')
.delete('/posts/:id', 'PostController.destroy');The Sails router is available at sails.router and provides lower-level routing functionality:
Bind new route(s) with advanced options:
sails.router.bind(path: String|RegExp, bindTo: String|Object|Array|Function, verb?: String, routeOptions?: Dictionary): voidParameters:
path (String|RegExp) - Route pattern or regular expressionbindTo (String|Object|Array|Function) - Target action, middleware, or handlerverb (String, optional) - HTTP method (default: all methods)routeOptions (Dictionary, optional) - Additional route configurationExamples:
// Basic route binding
sails.router.bind('/api/users', 'UserController.find', 'GET');
// Route with middleware chain
sails.router.bind('/admin/*', ['isAuthenticated', 'isAdmin', 'AdminController.dashboard']);
// Route with options
sails.router.bind('/upload', 'FileController.upload', 'POST', {
skipAssets: true,
cors: { origin: 'https://myapp.com' }
});
// RegExp route
sails.router.bind(/^\/api\/v(\d+)\/users$/, (req, res) => {
const version = req.params[0];
return res.json({ version, users: [] });
});// Remove existing route
sails.router.unbind(routeToRemove: Object): void
// Remove all routes
sails.router.reset(): void
// Rebuild all routes
sails.router.flush(routes?: Dictionary): voidExamples:
// Reset all routes
sails.router.reset();
// Flush and rebuild with new route configuration
sails.router.flush({
'GET /users': 'UserController.find',
'POST /users': 'UserController.create'
});Sails supports Express-style route parameters:
// Named parameters
sails.get('/users/:id', (req, res) => {
const userId = req.params.id;
return res.json({ userId });
});
// Multiple parameters
sails.get('/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = req.params;
return res.json({ userId, postId });
});
// Optional parameters
sails.get('/posts/:id?', (req, res) => {
const id = req.params.id || 'all';
return res.json({ posts: id });
});
// Wildcard routes
sails.get('/files/*', (req, res) => {
const filePath = req.params[0];
return res.json({ file: filePath });
});Access query parameters through req.query:
sails.get('/search', (req, res) => {
const { q, limit, page } = req.query;
return res.json({
query: q,
limit: parseInt(limit) || 10,
page: parseInt(page) || 1
});
});
// GET /search?q=sails&limit=20&page=2Routes can target different types of actions:
// Traditional controller method syntax
sails.get('/users', 'UserController.find');
sails.post('/users', 'UserController.create');
// Object-style target
sails.router.bind('/users', {
controller: 'UserController',
action: 'find'
}, 'GET');// Standalone action identity
sails.get('/login', 'entrance/login');
sails.post('/logout', 'account/logout');
// Action object target
sails.router.bind('/profile', {
action: 'account/view-profile'
});// Direct function
sails.get('/health', (req, res) => {
return res.json({ status: 'ok', timestamp: Date.now() });
});
// Async function
sails.get('/async-route', async (req, res) => {
const data = await someAsyncOperation();
return res.json(data);
});// Multiple middleware functions
sails.get('/protected', [
'isAuthenticated',
'hasPermission',
'UserController.dashboard'
]);
// Mixed middleware and functions
sails.post('/upload', [
(req, res, next) => {
console.log('Upload started');
next();
},
'isAuthenticated',
'FileController.upload'
]);Find route information for a given target:
sails.getRouteFor(target: String|Dictionary): {url: String, method: String}Parameters:
target (String|Dictionary) - Route target to search forReturns: Object with url and method properties
Throws:
E_NOT_FOUND - Route not foundE_USAGE - Invalid inputExamples:
// Find route by controller method
const route = sails.getRouteFor('UserController.find');
console.log(route); // { url: '/users', method: 'get' }
// Find route by action identity
const loginRoute = sails.getRouteFor('entrance/login');
console.log(loginRoute); // { url: '/login', method: 'get' }
// Find route by object target
const route2 = sails.getRouteFor({
controller: 'User',
action: 'create'
});
console.log(route2); // { url: '/users', method: 'post' }Get URL pattern for a route target:
sails.getUrlFor(target: String|Dictionary): StringParameters:
target (String|Dictionary) - Route target to search forReturns: String - URL pattern
Examples:
// Get URL for controller method
const url = sails.getUrlFor('UserController.show');
console.log(url); // '/users/:id'
// Get URL for action
const loginUrl = sails.getUrlFor('entrance/login');
console.log(loginUrl); // '/login'Route virtual requests (non-HTTP) through the router:
sails.router.route(req: Object, res: Object): voidParameters:
req - Request object (can be partial)res - Response object (can be partial)Example:
// Create virtual request/response
const mockReq = {
method: 'GET',
url: '/api/users',
headers: {}
};
const mockRes = {
json: (data) => console.log('Response:', data),
status: (code) => mockRes
};
// Route the virtual request
sails.router.route(mockReq, mockRes);Extract action identity from route targets:
sails.router.getActionIdentityForTarget(target: String|Dictionary): StringExamples:
// Controller method to action identity
const identity1 = sails.router.getActionIdentityForTarget('UserController.create');
console.log(identity1); // 'user/create'
// Object target to action identity
const identity2 = sails.router.getActionIdentityForTarget({
controller: 'User',
action: 'show'
});
console.log(identity2); // 'user/show'
// Direct action identity (pass-through)
const identity3 = sails.router.getActionIdentityForTarget('account/login');
console.log(identity3); // 'account/login'Get sorted list of all route addresses:
sails.router.getSortedRouteAddresses(): Array<String>Returns: Array<String> - Cloned and sorted array of route addresses
Example:
const addresses = sails.router.getSortedRouteAddresses();
console.log(addresses);
// ['GET /api/users', 'POST /api/users', 'GET /api/users/:id', ...]Routes can also be defined in config/routes.js:
// config/routes.js
module.exports.routes = {
// Basic routes
'GET /': 'PageController.home',
'POST /login': 'AuthController.login',
// RESTful routes
'GET /api/users': 'UserController.find',
'POST /api/users': 'UserController.create',
'GET /api/users/:id': 'UserController.findOne',
'PUT /api/users/:id': 'UserController.update',
'DELETE /api/users/:id': 'UserController.destroy',
// Wildcard routes
'GET /admin/*': 'AdminController.route',
// Route with middleware
'POST /upload': ['isAuthenticated', 'FileController.upload']
};Routes support various configuration options:
sails.router.bind('/api/secure', 'SecureController.data', 'GET', {
// Skip asset pipeline for this route
skipAssets: true,
// CORS configuration
cors: {
origin: 'https://myapp.com',
credentials: true
},
// Rate limiting (if configured)
rateLimit: {
max: 100,
windowMs: 60000
}
});The router instance exposes several properties:
sails.router.explicitRoutes // Reference to sails.config.routes
sails.router.log // Reference to sails logger
sails.router._privateRouter // Internal Express-like routerRoute errors are automatically handled by Sails:
// 404 handling - automatic for unmatched routes
sails.on('router:request:404', (req, res) => {
return res.status(404).json({ error: 'Not found' });
});
// 500 handling - automatic for route errors
sails.on('router:request:500', (req, res, err) => {
console.error('Route error:', err);
return res.status(500).json({ error: 'Server error' });
});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.
Install with Tessl CLI
npx tessl i tessl/npm-sails