Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: combine REST with Socket.IO

In the single page webapp I've recently built I'm getting data for my models using Restangular module. I'd like to add real-time updates to the app so whenever any model has been changed or added on the server I can update my model list.

I've seen this working very well in webapps like Trello where you can see the updates without refreshing the web page. I'm sure Trello webclient uses REST API.

What is a proper way to architect both server and client to archive this?

like image 632
Warwick Avatar asked Dec 12 '25 23:12

Warwick


1 Answers

First of all, your question is too general and can have a lot of solutions that depend on your needs and conditions.

I'll give you a brief overview for a single case when you want to leave REST APIs and add some realtime with web sockets.

  1. Get all data from the REST -- Sokets for notifications only.

    Pros: Easy to implement both server side and client side. You only need to emit events on the server with info about modified resource (like resource name and ID), and catch these events on the client side and fetch data with REST APIs.

    Cons: One more request to the server on every notification. That can increase traffic dramaticaly when you have a lot of active clients for a single resource (they will generate a lot of reverse requests to the server).

  2. Get initial load from the REST -- Sockets for notifications with data payload.

    Pros: All info comes with the notification and will not cause new requests to the server, so we have less traffic.

    Cons: Harder to implement both server side and client side. You will need to add data to all the events on the server. You will need to fetch data from all the events on the client side.

    Updated according to the comment

    As for handling different types of models (just a way to go).

    Client side.

    1. Keep a factory for each model.
    2. Keep in mind that you need realtime updates only for displayed data (in most cases), so you can easily use memory caching (so you can find any entity by its ID).
    3. Add listener for every type of changes (Created, Updated, Deleted).
    4. In any listener you should call some initObject function, that will find entity in the cache by ID and extend it, if there is no entity with such ID, just create a new one and add it to cache.
    5. Any Delete just removes an entity from the cache.

    Any time you need this resource, you should return the link to cache object in order to keep two way databinding (that is why I use extend and not =). Of course, you need to handle the cases like: "User is editing the resource while notification about deleting comes".

    Server side.

    1. It is easier to send all the model then just modified fields (in both cases you must send the ID of resource).
    2. For any Create, Update, Delete event push event to all engaged users.
    3. Event name should contain action name (like New, Update, Delete) and the name of resource (like User, Task etc.). So, you will have NewTask, UpdateTask events.
    4. Event payload should contain the model or just modified fields with the ID.

    Collection changes can be handled in two ways: with add/update/remove items in collection or changing all the collection as a whole.

All modifications like PUT, POST, DELETE are made with REST of course.

I've made a super simple pseudo gist for the case 1). https://gist.github.com/gpstmp/9868760 but it can be updated for case 2) like so https://gist.github.com/gpstmp/9900454

Hope this helps.

like image 72
Peter Gerasimenko Avatar answered Dec 15 '25 14:12

Peter Gerasimenko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!