Expose webservice directly to webclients or keep a thin server-side script layer in between?
I'm developing a REST webservice (Java, Jersey). The people I'm doing this for want to directly access the webservice via Javascript. Some instinct tells me this is not a good idea, but I cannot really explain that instinct. My natural approach would have been to have the webservice do the real logic and database access, but also have some (relatively thin) server-side script layer (e.g. in PHP). Clients would talk to the PHP layer which in turn would talk to the webservice. (The webservice would be pretty local to the apache/PHP server and implicitly trust calls from the script layer. The script layer would take care of session management.) (Btw, I am not talking about just hiding the webservice behind an Apache which simply redirects calls.)
But as I find myself at a lack of words/arguments to explain my instinct, I wonder whether my instinct is right - note that while I have been developing all kin开发者_StackOverflow社区ds of software in all kinds of languages and frameworks for like 17 years, this is the first time I develop a webservice.
So my question is basically: what are your opinions? Are there any standard setups? Is my instinct totally wrong? Or partially? ;P
Many thanks,
Max
PS: I might add a few bits of information about the planned usage of the whole application:
- will be accessed by different kinds of users, partly general public, partly privileged
- thus, all major OS/browser combinations can be expected as clients
- however, writing the client is not my responsibility
- will potentially have very high load/traffic
- logic of webservice will later be massively expanded for another product which is basically a superset of the functionality of the current project
- there is a significant likelihood that at some point an API should be exposed which can be used by 3rd party developers - obviously, with some restrictions
- at some point, the public view of the product should become accessible via smartphones, too (in other words, maybe a customized version of the site to adapt to the smaller display and different input methods)
I don't think that accessing a REST webservice directly via e.g. JavaScript is generally a bad idea, because that what the REST architecture is designed for. For your usecase you might have some implications to consider:
- Your webservice will have to take care of user management. Since the REST architecture does not support a server side session state you will have to do authentication and authorization on every request. Users will have to maintain their state on the client side.
- Your webservice implementation will have to take care of issues like caching and load balancing and all the other things you might have assigned to e.g. the PHP "proxy" script
For your requirements:
all major OS/browser combinations can be expected as clients
Since you webservice will only deliver data (e.g. JSON or XML) this should not be a problem. The JavaScript part just has to take care to issue the correct requests.
will potentially have very high load/traffic
If you strictly follow the REST architecture you can make use of http caches. But keep in mind that the stateless nature will always cause more traffic.
logic of webservice will later be massively expanded for another product which is basically a superset of the functionality of the current project
The good thing about open webservices is that you can loosely couple them together.
there is a significant likelihood that at some point an API should be exposed which can be used by 3rd party developers - obviously, with some restrictions
Again, with RESTful webservice you already have an API exposed for developers. It is on your clients to decide if this is a good or a bad thing.
at some point, the public view of the product should become accessible via smartphones
Another pro for making your REST webservice publicly accessible. Most smartphone APIs support HTTP requests, so you will just have to develop the GUI for the specific smarphone platform that makes direct calls to the webservice.
Firstly I am just extending on what Daff replied above. I am extending Daff's answer from the point of my learning or designing and implementing RESTful WebServices and please note that I am still learning.
When I started learning RESTful WS with Java, Jersey (0.3 IIRC), I had similar questions and the primary cause for that is "Total" mis-conception about RESTful Architecture. The most "Grave" mistake I performed was using JAXB for XML and Jackson for JSON (de)serialization directly from/to the persistence beans. This totally violates the REST principal and hence creating some vital issues in creating a high performance, highly available, scalable web service.
My mistake was, thinking in terms of API a.k.a Service, when we think RESTful WS we should forget "API" and think Resources. We should take great care in interlinking resources. My understanding of this only came after reading this, I suggest it to anyone wanting to create their own web service. My conclusion is what is Resource is to RESTful WS/Architecture what API to a native interface or SOAP Web Service. So I would suggest design your resources with care and understand that there is no limit in how resources your WebService may have.
So here comes how I concluded in implementing systems exposing an "API" through RESTful WS. I create an API which deals communicating with business entities, for example, PersistentBook, which contains either Id of PersistentAuthor or the object itself. All business logic considering persistent entities lie in the API implementation layer.
The web service layer uses the API layer to perform its operations on resources. Web service layer uses persistent entities to generate representations of beans and vice versa, the key feature here would be PersistentBook's representation would have a URI to the PersistentAuthor. If I want to use automated (de)serialization I create another domain layer, e.g. Book, Author etc.
Now as Daff mentioned caching would be inevitable, my checkpoints for them are -
- Support for 'Cache-Control', 'Last-Modified', 'ETag' response headers and 'If-Modified-Since', 'If-Match-None' request headers are key. Note from my more recent learnings - use 'Vary' header in case of varying representations (content negotiation) based on 'Accept' header.
- Using a server side caching such as Squid, Varnish in case clients do not use caching. One thing I learnt having all the right header support counts for nothing if clients do support them and in fact increases the cost in terms of computation and badnwidth ;)
- Use of Content-Encoding.
精彩评论