use-case / intro / SailsJS

51 views
Skip to first unread message

Rob Wormald

unread,
Apr 3, 2015, 8:01:43 PM4/3/15
to angular-...@googlegroups.com
Thought I'd introduce myself too, after ranting about fetch in the other thread. I'm Rob, I work in Palo Alto with a little healthcare startup called Jiff. My only other claim to fame is the super-awesome open-source lib I wrote/ripped off from $http for binding Angular to SailsJS, which is a nodeJS powered REST/Websocket framework powered by Express and Socket.io, inspired by Rails. 

Two things I wanted to mention (I had a brief conversation with Jeff about a year ago re: this topic, but I figure this is the right time to bring it back up)

From a design point of view, Sails' sister project is an ORM called Waterline - it's main thesis is that its a cross database ORM. It employs a simple adapter interface (see https://github.com/zohararad/sails-rest/blob/master/SailsRest.js for an example of an HTTP adapter) to mediate between CRUD and whatever datasource you're using. It'll even get as clever as doing cross-database/datasource joins, though how successful that is often depends on the low level capabilities of the datasource itself. 

From an here-is-where-observables-can-really-be-awesome point of view:

Out of the box, Sails provides "blueprints" - these are automatic REST endpoints (like rails does) based on Models - though they are designed for production use (where appropriate and with appropriate middleware/policies in front). The really interesting thing about these is that in addition to working beautifully with $http / $resource over HTTP, they also support REST-over-websockets (bear with me on this...!) 

Assuming I have a ChatMessage model in Sails, I have a GET /chatmessage endpoint ready to go:
$http.get('/chatmessage')
 
.then((res) => res.data)
 
.then((messages) => {
   
/do stuff with messages
 
});


Additionally, if I connect via socket.io, I can leverage the same endpoint like this:

//open socket connection
let socket
= io('http://localhost:1337');

//create a request
let request = {url:'/chatmessage'};

//send the request
socket
.emit('get',request,(response) => {
 
//do stuff with response.
});

//retrieving records automatically subscribes you to changes, listen for them
socket
.on('chatmessage', (pushMessage) => {
 
//do something with newly pushed data
});



That's the most basic usage, and in angularSails (my lib), I basically did the same in $http-style:
//the $sailsSocket service uses the same API as $http for ease of use/swapping
$sailsSocket
.get('/chatmessage')
 
.then((response) => response.data)
  .then((messages) => {
   
//do stuff with messages
 
});
//listen for user events, integrated with the digest cycle...
$sailsSocket
.subscribe('chatmessage', chatMessageEventHandler);


Then, if another user created a new message:
let newMessage = { text: 'hello world' };

$sailsSocket
.post('/chatmessage', newMessage)
 
.then(...

I get notified because I'm listening (having previously fetched and subscribed):
$sailsSocket.subscribe('chatmessage', chatMessageEventHandler);

const chatMessageEventHandler = (pushMessage) => {
 
//push message looks like
 console
.log(pushMessage); //{ verb: 'created', data: { id: 1, text: 'hello world', createdAt: '2015-04-01..' }};
}

(note that I realized some time later I could have just provided a replacement $httpBackend instead of cloning the entirety of $http, but it was a good learning experience :) 

Sander posted a snippet in the other thread related to this, and it's totally clear to me that Observables would be awesome in this context, so I wanted to put it forward as a use-case for angular-data2. I tried making a variety of $sailsResource-esque implementations, and they mostly worked, but they never felt super clean to me (listen for message, lookup in cache in ChatMessage service, update reference). An adapter based data layer that supported this sort of usage would be amazing (happy to see Ward from Breeze, Breeze is awesome! - I now realize I missed an opportunity for a Sails/Breeze tie in...) 

Last month the Sails team introduced their new project called Treeline, which is powered by the same stack as above, with a GUI for building backend services. I'll be supporting that as well and rebuilding the sailsSocket stack for the ES6/no-digest-loop world. One of things we're focusing on is providing super easy to use client SDK's (a la $angularFire or $sailsSocket), so here I am.

I did a quick demo at work the other day, repos are here and here if you'd like to try it out. See also a sketch for the above functionality for ng2 - https://github.com/robwormald/ng2chat/blob/master/src/services/SailsIOClient.js - which i'm now going to have a go at doing with Observables.

Cheers!

Rob

Reply all
Reply to author
Forward
0 new messages