3 minutes
Real-Time APIs with Sails’ Enhanced ORM
Summary
Sails.js v1.5 enhances its Waterline ORM with built-in real-time features: automatic WebSocket support for models, pub/sub events on CRUD operations, and flexible blueprint actions. You can now expose live data endpoints with minimal code, letting clients subscribe to model changes and receive updates instantly (sailsjs.com, sailsjs.com).
1. Introduction
Sails.js follows an MVC pattern with Waterline as its ORM. Real-time interactivity, like live chats or dashboards, used to require manual Socket.io wiring or external libraries. In v1.5, Waterline emits lifecycle events you can subscribe to, and Sails’ blueprints auto-generate WebSocket endpoints, dramatically reducing boilerplate.
2. Real-Time ORM Enhancements in v1.5
2.1 Model Pub/Sub API
Every Waterline model now supports .publish()
, .publishCreate()
, .publishUpdate()
, and .publishDestroy()
methods inside lifecycle callbacks, and .subscribe()
on the client to listen for these events. For example, in api/models/Message.js
:
// api/models/Message.js
module.exports = {
attributes: {
text: { type: 'string' },
user: { model: 'User' }
},
afterCreate: async function(newlyInsertedRecord, proceed) {
// Broadcast to all subscribers
Message.publishCreate(newlyInsertedRecord);
return proceed();
}
};
Clients connect via Socket.io and call Message.subscribe()
to start receiving new message events automatically (sailsjs.com).
2.2 WebSocket Blueprints
Enable real-time blueprints in config/blueprints.js
:
module.exports.blueprints = {
shortcuts: true,
rest: true,
actions: false,
sockets: true
};
This generates routes like GET /message/subscribe
and server-side handlers that wire up Waterline subscriptions without extra code.
2.3 Optimistic Updates & Live Queries
Use skipAllLifecycleCallbacks
on queries to reduce latency and push changes directly, and leverage watch()
to observe query result changes in real-time:
// Subscribe to 'online' users
User.watch(req);
User.find({ online: true }).exec((err, users) => {
// initial data
});
// Later, when a User updates online=true, subscribers get notified
(sailsjs.com).
3. Enabling Real-Time Endpoints
Configure Sockets (
config/sockets.js
):module.exports.sockets = { onlyAllowOrigins: ['http://localhost:1337'], grant3rdPartyCookie: false };
CORS for WebSockets: Ensure
origin
settings allow your client domain.Auto-Room Naming: Models use auto-generated rooms (
modelName
), e.g., allMessage
subscribers join themessage
room.
4. Use Cases & Code Examples
4.1 Live Chat
Server (Message model):
// afterCreate in Message.js (shown above)
Client (browser):
<script src="/js/socket.io.js"></script>
<script>
const socket = io();
socket.get('/message/subscribe', (data, jwr) => {
console.log('Subscribed to Message room');
});
socket.on('message', msg => {
if (msg.verb === 'created') {
renderMessage(msg.data);
}
});
</script>
4.2 Real-Time Dashboard
Track order counts:
// api/models/Order.js
afterCreate(newRec, next) {
Order.publishCount({ count: await Order.count() });
next();
}
Clients subscribe to Order.subscribe()
and listen for 'order'
events to update charts live.
4.3 Collaborative Editing
Use granular rooms per record:
// Client: subscribe to specific document
socket.get(`/document/${docId}/subscribe`, () => {});
socket.on('document', update => applyPatch(update));
Server emits via Document.publishUpdate(record.id, patch)
, notifying only clients in that doc room.
5. Security & Best Practices
- Authenticate Socket Connections: Use
sails.config.session
or custom middleware to validate tokens ononConnect
(sailsjs.com). - Scope Subscriptions: Avoid global pub/sub; keep clients in specific rooms to reduce noise and enforce permissions.
- Rate Limiting: Implement server-side checks to prevent event floods (e.g., max messages/sec per user).
6. Full Example Walkthrough
Generate a new Sails app:
sails new realtime-app cd realtime-app sails generate api Message
Update
Message.js
withafterCreate
hook.Enable blueprints in
config/blueprints.js
.Set CORS origins in
config/sockets.js
.Run the app:
sails lift
Open client: Use the browser snippet to subscribe and send GET/POST requests via Socket.io or the REST endpoint to create messages.
7. Conclusion & Further Reading
In Sails v1.5, Waterline’s real-time pub/sub and WebSocket blueprints let you build live APIs with minimal setup. From chat apps to dashboards and collaborative tools, you can expose and secure real-time endpoints directly from your models.
Further Reading
- Waterline ORM reference: https://sailsjs.com/documentation/reference/waterline-orm
- WebSockets in Sails: https://sailsjs.com/documentation/reference/websockets/sockets
- Blueprint API: https://sailsjs.com/documentation/reference/blueprint-api