Oisin Hurley wrote:
Hi Bert,
I am still at the point where I am trying to get my head really
wrapped around how Tuscany works
I will be travelling the same road soon ;)
Have you put much thought towards the subject of a REST binding? Are
there things about which you believe we should be aware?
Well, the thing that comes to mind first is the mismatch between
the basic REST approach of using a fixed set of 'verbs' richly flexible
data and the Interfaces approach, which uses an open-ended set of
'verbs' (read: operations) and constrained strongly-typed data.
[small REST primer - skip if you know all this stuff]
The short document at [0] below characterises some of the issues of
developing a (Web) service using REST principles and is useful and
the wikipedia link at [1] has a good example (generic, not Tuscany
specific) :
Say you have a service that has methods
getUser()
addUser()
removeUser()
updateUser()
then you might use code like:
exampleAppObject = new ExampleApp("example.com:1234")
exampleAppObject.getUser()
to get details of a user. This is the interface or unconstrained
verbs approach.
Now, let's flip over to a REST means of getting the same
information. In this case, you are limited to small set of
well-defined operations, which map very well to the CRUD [3]
operators that a persistence system must provide. Because
of this stricture, you need to ramp up the diversity of
nouns (or resources, or maybe objects, but really the concept
of a resource may not equal an object in programming terms,
many resources could be 'supported' by a single object).
These resources (which is the accepted term) are represented,
uniquely, and immutably, by URIs. So taking the example
above and REST-ing it you get resources:
http://example.com/users/
http://example.com/users/{user} (one for each user)
and then you might use code like:
userResource = new Resource("http://example.com/users/001")
userResource.get()
and you get the same information as the Interface-y example
previously.
REST is liked by many, for many reasons, but one good on is
that it's scalable (the web is an
example, although there is an extra factor that makes the
web scalable and that is the 404) in the sense that everyone
supports the same 'interface' and the semantics of the interface
are simple and clear.
In practical terms, this means that you can just join the
web, as a resource, and you will immediately fit in. No adapters
required :)
[end of small REST primer]
My interest in responding to your initial mail was that I am
currently attempting to use RESTian principles in another
project and I am finding myself making lots of interesting
decisions that I would not have made using the Interface
approach that I have used for more years than I care to
remember. Using the REST principles has deeply impacted they
way I've approached the development of the development of
the project -- in a good way :)
I'm sure you've noticed the example I gave earlier on the
programming model is client-specific and so impacts on only
part of a prospective RESTian addition to Tuscany. There is an
impact on the server too, and that's a direct consequence of
the 'few verbs' approach - talking from a programming language
perspective, every 'servant' (or resource implementation may
be a better way to put it) will have a tiny interface.
My point is that if Tuscany wants to support REST style -
a goal which I think is good, right and true - it's a job
that will involve constructing a binding extension,
re-working the Basic Client Model (see 1.3 in Java C&I spec)
and adding some new annotations to the Java interface (or
maybe adding a new interface type). Note that the same will
apply to other language mappings too since REST is language
neutral (it's also protocol neutral too as an architectural
style, but assuming HTTP as the #1 priority would be safe
enough :)
On the annotations I mentioned, consider something like:
package services.hello;
import org.osoa.sca.annotations.*;
@Remotable
public interface HelloService {
@RESTMethod(RestMethods.RETRIEVE)
@RESTBaseURIContext("/foo/bar/sossages")
String hello();
}
Here I've decorated the ubiquitous HW example from JC&I 1.2.1.1
with some spanky new annotations. This example indicates to the
runtime that the hello() method should be called on this interface
should the 'RETRIEVE' REST method (for HTTP this is 'GET') appear
on the dispatch, directed to a URI that starts with the string
specified in with the RESTBaseURIContext (now - this is probably
the wrong way to do it, but I just trying to illustrate the
broad outlines of an approach, i.e. I am making it up).
Note that the concept of XML/HTTP interchange may be RESTful,
but indeed may not. However, it is the basis for an implementation
of a RESTful approach (given HTTP as the transport) and is
useful in an of itself (especially for so-called Web 2.0 apps).
Methinks I've said enough for now, thank you for reading this
far if indeed you have ;)
cheers
--oh
[0] http://www.xfront.com/REST-Web-Services.html
[1] http://en.wikipedia.org/wiki/Representational_State_Transfer
[2]
http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
[3] http://en.wikipedia.org/wiki/CRUD_%28acronym%29
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
Oisin,
I was on a similar track, thinking about implementing a REST binding for
Tuscany C++. I agree with you that the REST pattern is about resources,
so we need to go further than just sending XML service requests over
HTTP, and understand what it means to work with resources in an SCA
application.
I was thinking about starting with something very simple like this:
In an SCDL component reference:
<reference name="customers">
<interface.resource type="http://my.business.objects/#Customer"/>
</reference>
and later in a composite reference:
<reference name="customers">
<binding.rest/>
</reference>
QName "http://my.business.objects/#Customer" specifies an XSD complex
type describing my Customer business object.
<binding.rest> loads my new REST binding extension that knows how to
send Customer resource requests over HTTP.
<interface.resource> indicates a fixed interface pattern with the
resource management / HTTP verbs.
In the client:
customers.get("http://my.customer.database.com/customers/1234"); returns
an instance of the Customer XSD complex type
customers.put("http://my.customer.database.com/customers/1234",
customerDataObject) updates customer 1234 with a Customer instance.
customers.get("http://my.customer.database.com/customers/") returns a
list of URIs to the customers.
On the server, the CustomerResource component implements the Customer
resource management verbs:
class CustomerResource {
DataObject get(string uri);
void post(string uri, DataObject customer);
void put(string uri, DataObject customer);
void delete(string uri);
list<string> list(string uris);
}
Also, I was thinking that somehow our REST work should tie in with the
DAS work that we're doing in Tuscany.
Thoughts?
--
Jean-Sebastien
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]