Hi Jervis, Liu, Jervis wrote:
>Hi, > >Based on the REST discussion we had before in this mailing list, I have >created an initial version of RESTful demo ( >http://svn.apache.org/viewvc?view=rev ><http://svn.apache.org/viewvc?view=rev&rev=448148> &rev=448148). The >intention is to show how to publish/consume RESTful services using the >programming models offered by CXF, for the time being, the primary focus is >demonstrating the REST based webservices using XML binding and JAX-WS >Provider/Dispatch. When CXF grows, we can add more RESTful capabilities into >CXF, for example, serving REST service using Spring POJO etc. Please note the >current effort is by no means to invent a "real" REST programming model. > >The RESTful communication scenarios covered by this demo are as below: > >A RESTful customer service is provided on URL >http://localhost:9000/customerservice/customers, users access this URI to >query or update customer info. > >A HTTP GET request to URL <http://localhost:9000/customerservice/customers> >http://localhost:9000/customerservice/customers returns a list of customer >hyperlinks, this allows client navigates through the application states. The >xml document returned: > ><Customers> > <Customer href=" <http://localhost/customerservice/customer?id=1234> > http://localhost/customerservice/customer?id=1234"> > <id>1234</id> > </Customer> > <Customer href=" <http://localhost/customerservice/customer?id=1235> > http://localhost/customerservice/customer?id=1235"> > <id>1235</id> > </Customer> > <Customer href=" <http://localhost/customerservice/customer?id=1236> > http://localhost/customerservice/customer?id=1236"> > <id>1236</id> > </Customer> ></Customers> > >A HTTP GET request to URL ><http://localhost:9000/customerservice/customers?id=1234> >http://localhost:9000/customerservice/customers?id=1234 returns a customer >instance whose id is 1234. The xml document returned: > ><Customer> > <id>1234</id> > <name>John</name> > <phoneNumber>123456</phoneNumber> ></Customer> > >A HTTP POST request to URL <http://localhost:9000/customerservice/customers> >http://localhost:9000/customerservice/customers with data: > ><Customer> > <id>1234</id> > <name>John</name> > <phoneNumber>234567</phoneNumber> ></Customer> > >updates customer 1234 with the data provided. > >The demo client side codes demonstrate how to sent HTTP POST with XML data >using JAX-WS dispatch and how to sent HTTP GET using URL.openStream(). > > > This is OK, but I don't see how this really gets anyone anything over writing their own using URLs and sources without the JAX-WS stuff. >There are some immediate improvements we can make to this demo: > >1. Remove the presence of WSDL files from both server and client side: REST >does not need WSDL file. JAX-WS provider/dispatch does not need WSDL too. >However our current implementation of provider/dispatch can not work without >wsdl, that's why you can see wsdl files in this RESTful demo. This needs to be >fixed > > I would definitely like to support the WSDL 2 HTTP/REST stuff though, its pretty cool. > >2. Support sending HTTP GET using JAX-WS dispatch: A HTTP GET request can be >sent by using URL.openStream or by using JAX-WS dispatch. Though I do not see >much benefit of using the latter, we do need to support it. According to >JAX-WS spec, this can be done by adding extra non-standard properties into >request context. A code snippet may look like below: > > Service service = Service.createService(); > service.addPort(portQName, " <http://cxf.apache.org/bindings/xformat> > http://cxf.apache.org/bindings/xformat", endpointAddress); > Dispatch<Source> d = service.createDispatch(portQName, Source.class, > Service.Mode.PAYLOAD); > > Map<String, Object> requestContext = d.getRequestContext(); > requestContext.put(Message.HTTP_REQUEST_METHOD, new String("GET")); > requestContext.put(Message.QUERY_STRING, queryString); > requestContext.put(Message.PATH_INFO, path); > > Source result = d.invoke(null); > >Does this look alright to everybody? > >Moving forward, I also want to see following things being discussed: > >1. How to expose an existing Web Service as a RESTful service. Say, I have an >existing Web Service written in JAX-WS, it would be really great if CXF can >help me to publish it as a RESTful service with minimal changes. In this case, >I see the need to support SEI on both server and client side. Several issues >involved: > >c. We will need a REST binding. This REST binding does have WSDL file. We can >have a wsdltorest tool to help generating the WSDL binding part for REST >binding. Probably this is the only thing users need to do to port an existing >web service to REST. > >a. How to map between REST resources and service operations. The easiest >approach is using fixed method names for the REST operations. I.e., given a >base URI context like <http://localhost/foo> http://localhost/foo (this is >the http:address in the wsdl file), a SEI method sayHi is mapped to URL ><http://localhost/foo/sayHi> http://localhost/foo/sayHi. Based on our previous >discussion, this does not conform to REST semantics very well. But one could >argue that the traditional applications are not REST anyway, we just make it >serving services with more REST flavors. > > > So I was chatting with James Strachan a bit at Javazone and we came up with a little set of java rest annotations. Two ways it could be put together. 1. The JAX-WS way @WebService public interface CustomerService { @Get @Rest(uri="/customers") public List<Customer> getCustomers(); @Get @Rest(uri="/customers/{id}") public Customer getCustomer(string id); @Post @Rest(uri="/customers/{id}") public void updateCustomer(Customer c); ... etc } 2. The Bean way @Rest(uri="/customers/{id}") public class CustomerService { private String id; public Customer get(); @Post pulblic void update(Customer c); } In this case "id" gets injected. Also, the @Post/Get/Put annotations get used if the method name doesn't follow convention. The @Rest annotation would support both the uri field and queryParameters So this annotation @Rest(uri="/customers", queryParmaters=new String[] { "id" }) would use an id query parameter instead of putting the id in the URI (i.e. /customers?id=123) We would also want to support an XML version of the annotations so we could map things to multiple URIs. >b. We need a method dispatch and parameter marshal/unmarshall mechanism >different from JAX-WS. For HTTP POST, the data sent on the wire should be a >raw xml , it is the URL who indicates the method being requested. The xml data >itself still needs to conform to xml schema in WSDL. For HTTP GET, we need >encode/decode method name and parameters into URL. > >Anyway, this story seems need a bit work to do. I see this as a valid >requirement but I am not very sure the above is the right way to approach. >FYI, Axis2 does support publishing existing SOAP service as REST service, but >it is a pure hack to me. ><http://people.apache.org/%7Esamisa/ApacheCon_EU_2006_REST.ppt> >http://people.apache.org/%7Esamisa/ApacheCon_EU_2006_REST.ppt > > Yeah, their REST stuff is VERY ugly. > >2. As Steve pointed out before, how to better support navigation of >application state via hyperlinks. "CXF has to enable and perhaps help the >server-side application to generate the URLs required to identify new >resources that it creates and tie servants/ implementations to them. >Applications have to play their part, too, by following the semantics of >HTTP, such as ensuring that GETs are idempotent, and ensuring that the URLs it >produces for its resources and state aren't just always temporary or >transient." > >3. Look into WSDL2's HTTP support to see what we can leverage from there. > > +1 - Dan -- Dan Diephouse (616) 971-2053 Envoi Solutions LLC http://netzooid.com
