users@jersey.java.net

RE: [Jersey] JAX-RS == REST? Or not? (was Re: [Jersey] What HATEOAS actually means)

From: Kevin Duffey <andjarnic_at_yahoo.com>
Date: Thu, 18 Feb 2010 12:42:39 -0800 (PST)

Hey all,

So I finally got the idea of this after I sent this last email. What you say Markus makes total sense now.. and I DO agree with how it would work. I totally love the idea of the client storing the state.

There are a few things however that I am hoping you can clear up.

The first is.. if the client is using my web cart service... and they need to add an item, why make a call to the server to add that item? Why not just simply build up their entire cart first with no calls to the server even if their end user adds items... then once the user wants to check out, the client sends the entire cart contents to my service at that point? Is that the idea.. or are you saying that the client consuming my API should send a POST /cart/<item id> every time their end user adds an item to the cart? I am hoping you are saying.. send the entire cart at one time.. not every time an item is added. Because I see no point in making a service API call to add an item OTHER THAN perhaps to simply validate that the item being added can be added. For example, if every time an item is added, we call the service.. the service can do a check on the inventory to see if the item is still in stock. I think this might be kinda slow.. but at least it
 would give a real time update of inventory and much faster response feedback. If an end user takes 2 hours to fill up their cart.. any item might have been already bought and out of stock... it would be much nicer to get faster feedback on that issue. Otherwise, since the cart is stored on the client, there is not much benefit of making a service call every time an item is added. But, with HATEOAS.. I am assumging the ADD TO CART is a URI that is passed back by the service when the user starts shopping.. so thus it would require a call every time. Maybe it is better.. just not entirely sure in all cases that it would be.

Should each call to add an item send the entire cart? I would hope not. I would guess, as I said above IF every add item requires a service call, it should only be the one item going to the service, not the entire "growing" cart of data. UNLESS (as I said above), each service request could check that ALL items in the cart are still in stock.. again.. in my example above, if I send ONLY the one item to add.. it can verify if it's in stock and give quick feedback. That's fine. But if we send the entire contents, the service could loop through all items, each time it's called and verify that all items in the cart are still in stock. Would you recommend this? If so, what about the growing size of data.. is that a potential issue, maybe not with this web cart example, but perhaps with other types of data that could be much larger..the more you add, the longer it will take for each request to send more data and get it all back.

Assuming either/both of the above are true (you send item or entire cart on every request), I am assuming that the client's "state" of the cart is still ok.. and any response back would simply be items that are no longer in stock (in which the client would 'remove' those items from their stateful cart), or the item(s) added to the cart (in which the client would 'add' those items to their stateful cart)?

I am also wondering about man-in-the-middle issues.. where by if the client sends all the stateful data every request.. I assume it must go encrypted to avoid potential man-in-the-middle attacks.. perhaps this is a bit contrived, but let's say someone intercepts the request and adds 5000 items right before the "pay" step occurs. I am curious how the payloads are handled in this respect.. but I suspect it's case by case basis.. if it needs to be secure, the xml/json/<whatever> data gets encrypted before sent, and decrypted once a response comes back?


So I completely get the notion of stateless now in how you describe, and like I said, it does make sense... for the most part. I totally would MUCH rather each individual client store 500 bytes of data.. where they are invidivual machines.. than my server having to have 256GB of memory or a horizontal stack of servers with load balancer and such just to handle 10000's of users each with 500 bytes of data. Naturally this makes it FAR easier on the server side to scale, and thus each server can handle WAY more clients than the other way around. However.. I am still having a hard time figuring out how to explain to consumers of my service(s), that they will need to maintain all the state, pass it back and forth, etc. I still feel that it will probably scare a lot of would be developers from using my service. While the web cart is an example.. I have a couple of ideas I am working on that I can't discuss right now, but will potentially involve making some
 money from them.. and their are direct competitors out there to the services I want to provide... and I am trying to fathom how I explain to developers that in order to maintain a pure REST api, they must do potentially a lot more work on their side to use my API. By putting everything on the server as I and many others I think are doing, the use of my API is extremely easy. It makes it very appealing to consumers of my services that they simply make some get/post/put/delete calls with minimal effort and voila! Trying to say "Hey.. I know those other APIs do more for you than mine does..but mine is a PURE rest implementation..." I think I am going to have a hard sale at best.. worse case very few if any will want to use my service.

Now, having said that, I know I can go either way. I can provide both if I wanted to. There is certainly no reason why I can't give a pure REST implementation, but also provide the one where I store the state on the server side as well. But, doing something like that would most likely end up everyone using the easier of the two, and I am in that situation that you are saying "why would you want to do it this way"... why store state and have to deal with scaling issues.

I'll give you one reason why. If the consumers of my service are one-off clients.. a mobile phone, desktop app, etc.. then it is VERY easy to support the pure REST api. Each individual device can house a little bit of memory and my service is pure stateless...yay.. win win. BUT.. what if the consumer of my API is a web site that is providing a user interface of their own for potentially 1000's of users. If the end user is a store front (to use the web cart service analogy), they now have to deal with scaling their web site to handle those potential 10000's of users shopping on their site. In this scenario, using my cart service makes no sense for them. I provide nothing of value to those types of API consumders because I am shifting the "ease" of scalability that they could avoid if my service dealt with the full state.. back on to them. I can see where a web cart service that handles state is VERY appealing to store front web sites. They no longer need
 to worry about scaling to handle session fail over. My service is hugely beneficial because I've alleviated a major headache for them. They can worry about their pretty user interface and the products they sell, knowing that my cart service provides them the inventory/cart storage/checkout process. It's worth it to them to pay me a little bit to use that.

So I ask in this above scenario.. I guess I simply say "this is an HTTP API that is not completely RESTful, but close to it..." maybe even explaining why it's not 100% REST because I could not provide this service if it was?



--- On Thu, 2/18/10, Markus Karg <markus.karg_at_gmx.net> wrote:

From: Markus Karg <markus.karg_at_gmx.net>
Subject: RE: [Jersey] JAX-RS == REST? Or not? (was Re: [Jersey] What HATEOAS actually means)
To: users_at_jersey.dev.java.net
Date: Thursday, February 18, 2010, 11:43 AM