I'm writing a web-app that I expect will be used by desktop
applications in the future, so am aiming to write an underlying REST
service that both web-app and desktop apps can use. I have found
web.py to be just what I need (i.e. understandable and very clean), so
thanks! I'm an experienced programmer but an inexperienced web-
programmer and I have a question about the most efficient, yet still
maintainable, way to architect my web-app and underlying service.
Apologies if some of the following is obvious to you. Below I have
tried to work through to a solution -- that I still have some
questions about -- and am hoping you will be able to give some advice
on how I should proceed.
I already know the URI structure I want to expose as a RESTful
service. A lot of what the web-app will do is just delegating to this
service; sometimes the web-app's code.py will want to make calls to
the service and sometimes AJAX requests will need to be made. My app
is very data-oriented, so I'd like to use (almost) the same URI
structure for both the web-app and the REST service -- the web-app
will mostly just be a pretty front-end. Ultimately, I would like to
have the following hosts set up.
www.domain.com -- the web-app, which dresses up the REST service in
an attractive way for users. I have written quite a bit of this.
api.domain.com -- the REST service itself.
Some example URIs:
www.domain.com/users/matatk -- a user profile web page
api.domain.com/users/matatk -- returns XML or JSON representing the
user, depending on content-type requested.
(This is very simplified -- I know that most classic user profile data
like email addresses could be much more efficiently obtained by the
web-app from the database directly. However, some of the stuff is
more complex; you'll have to trust me on that I suppose.)
It's possible that in future I might have the following, too.
api.domain.com/v1/ -- i.e. different versions of the API.
(or maybe v1.api.domain.com, though that would involve more vhosts
being set up...)
The web-app uses a cookie to identify the user (but no session data --
I read the thread about that and found it very interesting!), whereas
the REST API will probably start with HTTP basic auth and move to
OAuth when I am more experienced.
I'd like to use the REST API from within the web-app as much as
possible, to avoid duplicated code, but I have some questions as to
established best practice for doing this.
// Totally separate web-app and REST service
(This one doesn't seem practical to me but is useful as a starting
point.)
One way could be to totally separate the web-app and service and have
each in their own code.py on separate vhosts. The web-app (either in
code.py or in AJAX requests from the client) would have to
authenticate on behalf of the user with the REST service whenever the
web-app wants to use it, which would be quite a lot. This seems
somewhat insecure, as I imagine I'd have to provide the Authorization:
header to the JavaScript code that runs on the client so it could make
the request on the user's behalf -- urgh!
Both the web-app and service would have to have their own URLs
structure and code.py file. I suppose this would make backwards-
compatibility easier, because as long as the underlying database
doesn't change, I can just add new URI trees at api.domain.com/v1,
v2, ...
This also seems very inefficient, because my web-app would have to
talk HTTP to the REST service, that in this case will be running on
the same machine, so I am not considering it.
// Separate servers, with a shared library
I suspect it would be possible to put the meat of the common code
between web-app and service into a python library (that imports webpy)
that both vhosts have access to. This would mean that the web-app's
code.py wouldn't need to pass any authentication information to the
REST service. Visiting www.domain.com/users/matatk with a browser
would result in the web-app calling a function in the shared library
to get the raw data to be formatted attractively for the user, rather
than it requesting a URI on api.domain.com.
The area I am having problems with conceptually is the case when an
AJAX request from the client comes to the REST service -- in that case
an Authorization: header would be expected rather than a cookie to
identify the user, and the REST service, having its own separate
code.py on a different vhost to the web-app, would not have access to
the session to see if the user had successfully logged-in.
I can think of two solutions to this:
1. Assuming that AJAX requests from the browser would be recognised as
being part of the logged-in session that the browser is engaged in, I
could make the AJAX requests go to www.domain.com/users/matatk.json,
for example. Then the web-app could call the shared library, as
opposed to api.domain.com, to get the information out. This is ugly
because it results in breaking the REST principle of doing content-
type negotiation in HTTP, rather than polluting the URI space with it.
2. Maybe there is some way I could form an AJAX request that includes
the Accept: header, such that I /could/ request the JSON form of
www.domain.com/users/matatk through the AJAX request. Surely this is
possible? But it does rely on the AJAX request being seen as part of
the logged-in session by the web-app and I'm not sure if that would be
the case or not.
Overall, it seems using a library is the better approach; there might
be some overhead from importing webpy in the shared bit, but this way
seems just-about efficient yet also quite maintainable. It would
require me to write the REST service's code.py in such a way that it
does all the authentication and authorisation work and then just calls
the shared library to actually do stuff. I'm confused, however, as to
how the AJAX calls made by an client who has authenticated with the
web-app, could be detected as authenticated by the REST app -- would
solution 1 or 2 above work?
Does anyone else use this approach in their application+services? Is
there another way that I have missed?
Many thanks for your time and also for any advice you might be able to
give.
best regards,
--
matatk
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"web.py" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [email protected]
For more options, visit this group at http://groups.google.com/group/webpy?hl=en
-~----------~----~----~----~------~----~------~--~---