Search code examples
javascriptangularjsrestbackbone.jssingle-page-application

REST API, tracking changes in multiple resources, front-end synchronization


I have a system with quite complex business logic, so far I have around 10-15 database tables (resources), and this number is growing. The front-end for user is angularjs single page application. The problem is communication with back-end and keeping angular front-end sychronized with back-end data.

Back-end keeps all resources and relationships between them, this is obvious. And front-end fetches those resources and keeps copy of them locally to make interface much more responsive for user and avoid fetching data at every request. And this is awesome.

Server-side has many operations which affect many resources at once. What it means is that adding/removing/editing one resource (via REST api) can modify a lot of other resources.

I want front-end app data to be always fully synchronized with back-end data. This allows me to keep data integrity and keep my application bug-free. Any kind of desynchronization is a big "no no", it introduces hundreds of places where undefined behaviours could possibly occur in my front-end app.

The question is: what is the best way to achieve that? My ideas/insights:

  1. Business logic (modifying/editing/deleting resources, managing relationships, keeping data integrity) must be implemented only once. Doubling business logic implementation (one in front-end and one in back-end) introduces a lot of potential bugs and involves code duplication which is obviously a bad thing. If business logic was implemented in front-end, back-end still would have to validate data and keep their integrity - duplication of business logic. So, the business logic MUST be in back-end, period.

  2. I use REST API. When my front-end updates one resource (or many resources via PATCH method), a lot of side-effects happen in server-side, other resources get modified too. I want my front-end angular app to know WHICH resources got modified and update them (to keep full synchronization). REST returns only the resource which was originally requested to update, without other affected resources.

I know that that I could use some form of linking resources, and to send my original updated resource with links to other affected resources. But what if there are 100 of them? Making 100 requests to server is total performance kill.

  1. I am not very attached to REST, because my API is not public, it could be anything. I think that the best solution would be back-end sending back ALL modified resources. This would allow my front-end to always be in sync with backend, would be fast and would be atomic (no invalid intermediate state between multiple requests to server). I think that this architecture would be awesome. The question is: is this a common approach? Are there any protocols / standards / libs allowing me to do this? We could write it from scratch, but we don't want to reinvent the wheel.

  2. Actually, I think that having business logic in front-end and back-end would be good, but ONLY if it would be implemented once. This means Javascript back-end application. Unfortunately, at the time being, this is not possible solution for me.

Any insight will be welcome!

Added backbone.js tag, because question is much more about architecture than any specific technology.


Solution

  • You're on the right track and it is a common problem you're facing right now. As you said, in a REST world your API returns the requested / changed resource. A simple example of your problem:

    You - as user X - want to follow another user Y. The front end displays your own following counter (X) and the follower counter of the other user (Y). The http call would be something like:

    PUT /users/X/subscribe/Y
    

    The API would return the user Y resource but X is missing, or the other way around.

    To handle this cases I use an extended structure of my standard API response structure, my standard structure is:

    • meta object - includes the http status code and an explanation why this code got used, which app server processed the response and more
    • notification object - includes information of errors during processing (if any), special messages for developers and more
    • resource - the resource which got requested / modified, the name of this attribute is the resource type in singular for single resources (e.g. user) or in plural for resource collections (e.g. users)

      { meta: { status: 200, message: 'OK', appServer: app3 }, notification: { errors: [] }, user: { id: 3123212, subscribers: 123, subscriptions: 3234 } }

    In order to return also other affected resources und keeping the REST way + my static, standard response structure I attach one more object to the response called 'affectedResources' which is an array of all other affected resources. In this very easy example the array would include just the user X resource object. The front end iterates the array and takes care of all necessary changes front end wise.