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

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:
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.
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.
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.
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.

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.

Related

Building a web front end from an existing API

I'm building a front end web application from an existing (RESTful) API.
What is the best way to go about this? I'm assuming the new standard way to do this is through something like backbone.js.
I also want the pages to be different URL's and not have a single page application. That said, I'm guessing it's bad practice to request the page and then fire off async api requests when we might as well load the data from the server to start, right? What sort of architecture or technology should I be looking at so that I can reuse the API but not send off two requests to the server back to back, one to load the page, and one to load the data?
Backbone and other JavaScript "MV*" frameworks are definitely a great choice for performant event-driven UIs. You can use this design and have different pages and URLs. It just makes it easier and faster to do the asynch operations on a given page because you will have the relevant data in a JSON model and use a pub / sub pattern in an environment where views automatically update when data changes. Another advantage of this type of design is that you can have your data in models as opposed to walking the DOM to get data.
In addition to Girardi's answer, your concern about doing two request on initial page load - one for the page and one for the actual data - is a real problem.
One of the solutions is to bootstrap the initial data right into the page so you can skip the additional async request. This is called Model Bootstrapping. For example, you can place and additional <script></script> tag which will holds the bootstrapped model:
<script>
window.I_MODEL = [
{id: 1, name: "foo"},
{id: 2, name: "bar"}
]
</script>
then construct your model on the server side and with the help of some templating mechanism print the serialized model right into the page.
Search for backbone model bootstrapping, here is a right-to-the-point example: http://ricostacruz.com/backbone-patterns/#bootstrapping_data
Well, it's not a bad practice to load page first and then requesting async data. keeping template(html) and data calls separate, you can exploit benefits of localStorage, browserCaching to maximum extent. Backbone doesn't inject any magic into your application, it's just provides a framework to organise your code and helps in avoiding some boilerplate code again and again.

Browser-based caching for remote resources

I have two REST-ful resources on my server:
/someEntry/{id}
Response:
{
someInfoAboutEntry: ...,
entryTypeUrl: "/entryType/12345"
}
and
/entryType/{id}
Response:
{
someInfoAboutEntryType: ...
}
The entryTypeUrl is used to fetch additional data about the type of this entry from the different URL. It will be bound to some "Detailed information" button near each entry. There can be many (let's say 100) entries, while there are only 5 types (so most entries point to same entryTypeUrl.
I'm building a Javascript client to access those resources. Should I cache entryType results in my Javascript code, or should I rely on the browser to cache the data for me and dispatch XHR requests every time user clicks the "Detailed information" button?
As far as I see it, both approaches should work just fine. The second one (always dispatching requests) will result in clearer code though. Should I stick to it, or are there some points I'm not aware of?
Thanks in advance.
I would definitely let the browser manage the caching, rather than writing a custom caching layer yourself.
This way you have less code to write and maintain, and you allow the server to dictate (via its HTTP headers) whether the response should be cached or not. If you write your own caching code you remove the ability to refetch stale data - which you would get for free from the browser.

Http methods differences

What is difference between
HTTPPOST
HTTPDELETE
HTTPPUT
HTTPGET
Normally used post and get method for submit form and i know them very well but want to know with delete and put method when and why they can be used to improve programming skills
What the different methods do depends entirely on how the remote web server chooses to interpret them. There is no fixed meaning. A server does not care if it sees GET or POST; rather, the code that ends up being executed to service the request does (and can decide to do anything, since it's code).
The HTTP protocol gives an official guideline for what kind of action each verb is supposed to trigger, which is:
GET: retrieve a resource
PUT: replace a resource with another, or create it if it does not exist
DELETE: remove a resource if it exists
POST: might do anything; typically used to "add" to a resource
However this mapping is ultimately governed by application code and is typically not respected by web applications (e.g. you will see logical deletions being enacted with POST instead of DELETE).
The situation is better when talking about REST architectures over HTTP.
In a nutshell:
GET = fetch a resource.
POST = update a resource.
DELETE = delete a resource.
PUT = create/replace a resource.
In HTML, only GET and POST are allowed. A typical web-development HTTP server will do nothing unless you have code (or configuration) to specify what you want it to do with the different HTTP methods.
There's nothing stopping you from updating user data in response to a GET request, but it's not advisable. Browsers deal with GET and POST differently, with respect to caching the request (a cached GET will automatically be reissued, but a cached POST will prompt the user to allow it to be resent) and many HTML elements can issue GETs, making them unsafe for updates. There are other HTTP methods too http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol.
Many people who claim to be RESTful will confuse HTTP POST and PUT with SQL UPDATE and INSERT. There isn't a direct correlation, it always depends on context. That is, what POST means depends entirely on the resource that you're interacting with. For example, creating a new entry on a blog could be a POST to the blog itself, or a PUT to a subordinate resource. However, a PUT, by definition, must always contain the entire resource.
Typically, you would not allow a HTTP client to determine the URI of a new resource, so a POST to /blog would be safer than a PUT to /blog/article-uri although HTTP does cater for appropriate responses should the server be unable to honour the intended URI. (HTTP is just a specification, you have to write the code to support it, or find a framework)
But as you can always achieve a PUT or DELETE use-case by POSTING to a parent resource responsible for its subordinates (i.e. POSTing a message to /mailbox instead of PUTting it at /mailbox/message-id), it isn't essential to expose PUT or DELETE methods publicly.
You can improve your programming skills by adopting REST principles to improve the visibility of the interactions within a system, it may be simpler to contextualise your interactions in terms of REST by having a uniform interface, for example.
REST is not HTTP though: http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm.

POST manipulation, Tamper Data and AJAX security issues

Frequently when I work on AJAX applications, I'll pass around parameters via POST. Certain parts of the application might send the same number of parameters or the same set of data, but depending on a custom parameter I pass, it may do something completely different (such as delete instead of insert or update). When sending data, I'll usually do something like this:
$.post("somepage.php", {action: "complete", somedata: data, moredata: anotherdata}, function(data, status) {
if(status == "success") {
//do something
}
});
On another part of the application, I might have similar code but instead setting the action property to deny or something application specific that will instead trigger code to delete or move data on the server side.
I've heard about tools that let you modify POST requests and the data associated with them, but I've only used one such tool called Tamper Data for Firefox. I know the chances of someone modifying the data of a POST request is slim and even slimmer for them to change a key property to make the application do something different on the backend (such as changing action: "complete" to action: "deny"), but I'm sure it happens in day to day attacks on web applications. Can anyone suggest some good ways to avoid this kind of tampering? I've thought of a few ways that consist of checking if the action is wrong for the event being triggered and validating that along with everything else, but I can see that being an extra 100 lines of code for each part of the application that needs to have these kinds of requests protected.
You need to authorize clients making the AJAX call just like you would with normal requests. As long as the user has the rights to do what he is trying to do, there should be no problem.
You should also pass along an authentication token that you store in the users session, to protect against CSRF.
Your server can't trust anything it receives from the client. You can start establishing trust using sessions and authentication (make sure the user is who she says she is), SSL/TLS (prevent tampering from the network) and XSRF protection (make sure the action was carried out from html that you generated) as well as care to prevent XSS injection (make sure you control the way your html is generated). All these things can be handled by a server-side framework of good quality, but there are still many ways to mess up. So you should probably take steps to make sure the user can't do anything overly destructive for either party.

Protecting my REST service, which I will use on the client side, from others to use

Let's assume that I have created my REST service smoothly and I am returning json results.
I also implemented API key for my users to communicate for my service.
Then Company A started using my service and I gave them an API key.
Then they created an HttpHandler for bridge (I am not sure what is the term here) in order not to expose API key (I am also not sure it is the right way).
For example, lets assume that my service url is as follows :
www.myservice.com/service?apikey={key_comes_here}
Company A is using this service from client side like below :
www.companyA.com/services/service1.ashx
Then they start using it on the client side.
Company A protected the api key here. That's fine.
But there is another problem here. Somebody else can still grab www.companyA.com/services/service1.ashx url and starts using my service.
What is the way of preventing others from doing that?
For the record, I am using WCF Web API in order to create my REST services.
UPDATE :
Company A's HttpHandler (second link) only looks at the host header in order to see if it is coming from www.companyA.com or not. but in can be faked easily I guess.
UPDATE 2 :
Is there any known way of implementing a Token for the url. For example, lets say that www.companyA.com/services/service1.ashx will carry a querystring parameter representing a TOKEN in order for HttpHandler to check if the request is the right one.
But there are many things here to think about I guess.
You could always require the client to authenticate, using HTTP Basic Auth or some custom scheme. If your client requires the user to login, you can at least restrict the general public from obtaining the www.companyA.com/services/service1.ashx URL, since they will need to login to find out about it.
It gets harder if you are also trying to protect the URL from unintended use by people who legitimately have access to the official client. You could try changing the service password at regular intervals, and updating the client along with it. That way a refresh of the client in-browser would pull the new password, but anyone who built custom code would be out of date. Of course, a really determined user could just write code to rip the password from the client JS programmatically when it changes, but you would at least protect against casual infringers.
With regard to the URL token idea you mentioned in update 2, it could work something like this. Imagine every month, the www.companyA.com/services/service1.ashx URL requires a new token to work, e.g. www.companyA.com/services/service1.ashx?token=January. Once it's February, 'January' will stop working. The server will have to know to only accept current month, and client will have to know to send a token (determined at the time the client web page loads from the server in the browser)
(All pseudo-code since I don't know C# and which JS framework you will use)
Server-side code:
if (request.urlVars.token == Date.now.month) then
render "This is the real data: [2,5,3,5,3]"
else
render "401 Unauthorized"
Client code (dynamic version served by your service)
www.companyA.com/client/myajaxcode.js.asp
var dataUrl = 'www.companyA.com/services/service1.ashx?token=' + <%= Date.now.month %>
// below is JS code that does ajax call using dataUrl
...
So now we have service code that will only accept the current month as a token, and client code that when you refresh in the browser gets the latest token (set dynamically as current month). Since this scheme is really predictable and could be hacked, the remaining step is to salted hash the token so no one can guess what it is going to be .
if (request.urlVars.token == mySaltedHashMethod(Date.now.month)) then
and
var dataUrl = 'www.companyA.com/services/service1.ashx?token=' + <%= mySaltedHashMethod(Date.now.month) %>
Which would leave you with a URL like www.companyA.com/services/service1.ashx?token=gy4dc8dgf3f and would change tokens every month.
You would probably want to expire faster than every month as well, which you could do my using epoch hour instead of month.
I'd be interested to see if someone out there has solved this with some kind of encrypted client code!
What you're describing is generally referred to as a "proxy" -- companyA's public page is available to anyone, and behind the scenes, it makes the right calls to your system. It's not uncommon for applications to use proxies to get around security -- for example, the same-origin policy means that your javascript can't make Ajax calls to, say, Amazon -- but if you proxy it on your own system, you can get around this.
I can't really think of a technical way to prevent this; once they've pulled data from your service, they can use that data however they want. You have legal options, of course; you can make it a term of service that proxying isn't allowed, and pull their API key if they don't comply. But most likely, if you haven't already included that in the TOS, you'd have to wait for, say, a renewal of their subscription to your service.
Presumably if they're making server-side HTTP requests to your service, those requests are all coming from the same IP address, so you could block that address. You'd probably want to tell them first, and they could certainly get around that if they wanted to.
With the second link exposed by Company A I don't think you can do much. As I understand it, you can only check whether the incoming request comes from Company A or not.
But each request issued to www.companyA.com/.. can't be distinguished from original request from Company A. Everyone they let in uses their referrer as a disguise.

Categories

Resources