RE: Response from POST
Nevermind - it looks as if the getResponse().setEntity() will accept my FileRepresentation and accomplish what I'd like to. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2710256
Restlet speed
Restlet does not seem to run as fast as I would expect. I was hoping someone could point me how to get it running faster. Looking at the examples, I've created a simple server: import org.restlet.Server; import org.restlet.data.Protocol; import org.restlet.resource.Get; import org.restlet.resource.ServerResource; public class SimpleServer extends ServerResource { public static void main(String[] args) throws Exception { // Create the HTTP server and listen on port 8182 new Server(Protocol.HTTP, 8182, SimpleServer.class).start(); } @Get public String toString() { return hello, world; } } I also have created a simple client: import java.io.IOException; import org.restlet.resource.ClientResource; public class SimpleClient { public static void main(String [] args) throws IOException { // Create the client resource ClientResource resource = new ClientResource(http://localhost:8182;); // Write the response entity on the console long startTime = System.nanoTime(); // If getMethod 1 is used, I get 3.12 seconds. // Setting getMethod 2 results in 2.30 seconds. int getMethod = 2; for( int i=0; i 10; i++) { if( getMethod == 1 ) resource.get().write(System.out); else new ClientResource(http://localhost:8182 ).get().write(System.out); } long endTime = System.nanoTime(); System.out.println( (endTime-startTime) / 10.0); } } If both are running on the same system, I get can process 10 requests in 2.3 or 3.1 seconds depending on the method used. I'm not sure why creating a new client resource is faster than reusing the old one. At any rate, I was hoping to run at least 100 in one second. Any thoughts on why this is slow? -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2703772
Re: Removal of extensions for upcoming versions
Second attempt without the typos J --- Hi all, While preparing for the release of Restlet Framework 2.1 M1 (due tomorrow), I’ve done some clean-up and removed modules that we won’t develop or support anymore. The goal is to focus our energy on the modules adding the most value to end-users rather than trying to integrate with everything cool technology around. I first had a look at the incubator and saw three modules that aren’t developed anymore: ·JXTA : technology for peer-to-peer networks which hasn’t evolved much since 2007 ·Shell : command line support for Restlet, which we prefer to cover using IDE tooling http://wiki.restlet.org/developers/172-restlet/361-restlet.html in the future ·Atmosphere : mostly empty, dependency on Servlet API, too much to do, too much overlap with the asynchronous Restlet API features… but interesting project to keep an eye on :) implementing a websocket connector on top of restlet would be a much less loss of band(cpu)width ;-) Atmostphere is too much oriented toward jersey and the dependency on the servlet even if it could be aleviated it is too much of work for a technology that have now less attraction (read tech lust) than websocket as a lot of libraries could make it available even for old browsers through a flash proxy. In addition I would like to remove the Grizzly and Netty extensions which were considered as experimental connectors in Restlet Framework 2.0. The new internal connector http://wiki.restlet.org/developers/172-restlet/354-restlet.html based on non-blocking NIO that will be available in version 2.1 M1 now provides similar advantages (fully decoupling HTTP connections and IO threads) and is already more complete from a HTTP coverage point of view. Relying on our own connector also has many advantages such as control of the IO/network layer allowing features such as TCP/IP connection blocking which would be possible a consistent manner across all extension connectors. I use Grizzly (for not good reason anymore) what is your suggestion for current development (i.e not in production) abandon it and switch to jetty as a safe bet for production cases and play with your new baby in developpement to test it ? ps : to bad you droped netty as it could be used outside of the http case for communicating with plain old socket oriented servers as it is more supported than apache mina. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2678111
reconstructing an HttpServletRequest from a Restlet request ?
I'm wondering how to integrate the Google Visualization Tookit Datasource Librairie inside a Restlet container (standalone version). The Google Visualization Toolkit allow allows to graph a lot of data in several graphs format and widgets (gallery here : http://code.google.com/apis/visualization/documentation/gallery.html ). There is a Google library that allow datasource buildup, lets say inside an application (Reslet). see an intro here : http://code.google.com/apis/visualization/documentation/dev/dsl_intro.html But when I look to the Java API, there is a high level requirement on the HttpServlet API that look at very simple parameters (e.g like domain and host request). So there is few high level API that looks like : DataTablegenerateDataTable(Query query, HttpServletRequest request) Generates the data table. (see here : http://code.google.com/apis/visualization/documentation/dev/dsl_javadocs/index.html) My question is : Would it be possible to implement a kind of HttpServlet Factory from a Restlet request and feed this object interface to such an external library ? (looking at the source it seems like there is no need to access low level Stream just some way to reconstruct a standard Sun HttpRequest parameters) I know I could use a web container, but I'd like to ask weird and twisted question ;-) (seriously I'm still not convince I need to grab a whole web container for my small app). -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2662372
Re: reconstructing an HttpServletRequest from a Restlet request ?
On 20/09/10 17:35, Vincent Nonnenmacher wrote: I'm wondering how to integrate the Google Visualization Tookit Datasource Librairie inside a Restlet container (standalone version). The Google Visualization Toolkit allow allows to graph a lot of data in several graphs format and widgets (gallery here : http://code.google.com/apis/visualization/documentation/gallery.html ). There is a Google library that allow datasource buildup, lets say inside an application (Reslet). see an intro here : http://code.google.com/apis/visualization/documentation/dev/dsl_intro.html But when I look to the Java API, there is a high level requirement on the HttpServlet API that look at very simple parameters (e.g like domain and host request). So there is few high level API that looks like : DataTablegenerateDataTable(Query query, HttpServletRequest request) Generates the data table. (see here : http://code.google.com/apis/visualization/documentation/dev/dsl_javadocs/index.html) My question is : Would it be possible to implement a kind of HttpServlet Factory from a Restlet request and feed this object interface to such an external library ? (looking at the source it seems like there is no need to access low level Stream just some way to reconstruct a standard Sun HttpRequest parameters) I know I could use a web container, but I'd like to ask weird and twisted question ;-) (seriously I'm still not convince I need to grab a whole web container for my small app). Vincent ! why are you bothering others with stupid question where the RTFM give you the answer here : http://code.google.com/apis/visualization/documentation/dev/dsl_key_concepts.html#nonservlet still having a Restlet way to implement a DataTableGenerator will allow for nice integration of Google visualisation API for Restleters. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2662374
Re: Prudence 1.0 RC1
On 12/09/10 02:39, Tal Liron wrote: I'm very happy to announce the first public release candidate of Prudence, an open source web development platform based on Restlet 2.0. http://threecrickets.com/prudence/ Prudence comes with a comprehensive 100-page manual, a complete example application and an extensive online reference. It's been in development for more than a year and has undergone a lot of testing in live production environments. Great work ! I tried it over this weekend and it sound like I could migrate back from an external ruby/sinatra for the UI computation part to prudence. Especialy the fact that with groovy support its far more easier to do some Restlet Ressource inner integration on the view side with very powerfull routings. If you've depended on JEE containers such as Tomcat or JBoss to deploy your Restlet apps, you might be happy to replace them with Prudence. Prudence acts as a Restlet-centric container, The documentation is very nice and the tutorial a breeze to play with ;-) Perhaps one area to document would be for Reslet developers showing them how they can enrich there own routing/mapping of ressources to view delivery with prudence with a scripting level layer of their choice. I feel it could solve some of my problems but with contrained time it somewhat scary to adopt on a latter stage something that taken from the outside look like an 'other radical choice for a latter projet', when there is perhaps small steps to follow to convert let say a freemaker/velocity view kind of mapping to a Prudence app. From that some parrallel side by side description on how to do things by hands with Restlet and doing the same with prudence would bring you some converts ;-) -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2658657
Re: Using a REST layer for UI and services
On 11/09/10 17:47, Jerome Louvel wrote: Hi all, Marc, Tal, would you mind updating the Powered by page in the community wiki so people can find out themselves about your projects based on Restlet? http://wiki.restlet.org/community/165-restlet.html Back to the original question, this is possible to use FreeMarker or Velocity templates in Restlet like you would do with JSP, but as Vincent pointed out, this require manual work for each REST resource you want to expose as HTML, in addition to JSON/XML. Good news, is that we are planning to simplify this binding in version 2.1 but associating the template files with representation beans based on the bean qualified class name. The converter service would allow the developer to indicate where the template lives, for example in the classpath next to the bean class or in a separate directory. That would be a nice addition even for other higher level frameworks like Prudence and Kauri as sometimes the ressource representation is right at Restlet level (considering it at the ressource/model layer). Let take an example in my small domain where I need to give XML responses to differents phones (manufacturers dialects) from the exact same ressource. Without your addition I'm forced to make contrieved routes for separating the REST URI added query parameters and then exposing in the REST routes some templating parameters (like a format). either through something like : GET ressource_path/queue/200 That list let say attributes for a phone queue 200 and then GET ressource_path/queue/200?template=aastra GET ressource_path/queue/200?template=cisco or adopting a view separation mapped to a template finder GET ressource_path/view/aastra/queue/200 and GET ressource_path/view/cisco/queue/200 in both case there is somewhat two layers (model and view) that get mixed still not getting the full view as for example I could have the ressource processed further. Having a bean annotation would do this kind of second routing (kinda like Prudence is doing on its nice routing over Restlets but at a lower level more in par with an OO decomposition). -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2658653
Re: Using a REST layer for UI and services
On 10/09/10 09:15, Marc Portier wrote: you might want to give http://kauriproject.org a try it has restlet and all its goodies underneath, but adds - a java and rest-service-wiring (based on spring and then some) - some templating, routing, and client-side ajax/js support (including a form-model) that helps out in this webservice to UI transition we're wrapping up a 0.4 release in the near future Hi mark, I admit I have looked at Kauri but some time ago and lack of documentation (and time to try) make me not considering it. I see that you have made lots of improvements on the doc side the mavenization is also nice, I will give it a try, thanks for the update ;-) -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2657525
Re: restlet and comet
On 09/09/10 15:18, Maxime Bégnis wrote: Thanks Vincent for your tips. I'm looking forward to this implementation of NIO. Regards, Maxime Bégnis On 09/09/10 15:18, Maxime Bégnis wrote: Thanks Vincent for your tips. I'm looking forward to this implementation of NIO. there is also the work being done on the Grizly v2 that implement client/server API for websockets have a look here : http://blogs.sun.com/oleksiys/entry/grizzly_2_0_websockets_support Regards, I looked at your Calenco projet and see that you are using Dojo so it's true that you can favor comet instead of websocket as dojo is far more advanced on the subject than say jQuery (which is my choice). For doing comet using Restlet I'm now (regarding that I don't use jetty that could change the deal completely I admit) pursuing the idea of having the UI (and so the comet/websocket real time update) be done by an other small server (Ruby based) in scheme where Restlet is used as the 'controled model' and the web-client subscription (done either automaticaly by bayeux subscription or websocket channels) is handled by this layer. So Restlet stay in its own paradigm. In such scenarii you could have this second server having some active 'subscription' from the Restlet engine in term of a REST request that carry what URI this server want to be notified of some events. The second server controling the UI-serving will itself do the comet/websocket handshake. like in : 1) [ ressources + inside/business events flow ] -- RESTful interface using Restlet 2) comet/websocket reactor -- Web clients and 2) make request to 1) like POST /uripath/ressource/event/notification with a REST Request URI that will be accepted by 2 then whenever there is a ressource change or event concerning the 'monitored' ressource 1) will just place the request with a aggreed uppon paylod (for example a RessourceRef) This is in par with idea like the PubSubHubHub things. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2657219
Re: restlet and comet
On 09/09/10 15:18, Maxime Bégnis wrote: Thanks Vincent for your tips. I'm looking forward to this implementation of NIO. Regards, Maxime Bégnis I looked at your Calenco projet and see that you are using Dojo so it's true that you can favor comet instead of websocket as dojo is far more advanced on the subject than say jQuery (which is my choice). For doing comet using Restlet I'm now (regarding that I don't use jetty that could change the deal completely I admit) pursuing the idea of having the UI (and so the comet/websocket real time update) be done by an other small server (Ruby based) in scheme where Restlet is used as the 'controled model' and the web-client subscription (done either automaticaly by bayeux subscription or websocket channels) is handled by this layer. So Restlet stay in its own paradigm. In such scenarii you could have this second server having some active 'subscription' from the Restlet engine in term of a REST request that carry what URI this server want to be notified of some events. The second server controling the UI-serving will itself do the comet/websocket handshake. like in : 1) [ ressources + inside/business events flow ] -- RESTful interface using Restlet 2) comet/websocket reactor -- Web clients and 2) make request to 1) like POST /uripath/monitored ressource/event/notification with a REST Request URI that will be accepted by 2 then whenever there is a ressource change or event concerning the 'monitored' ressource 1) will just place the request (as a client) with a aggreed uppon paylod (for example a RessourceRef). Then 2) could ask for more details using your own API. This is in par with idea like the PubSubHub[Hub] things. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2657216
Re: Using a REST layer for UI and services
On 06/09/10 13:26, webp...@tigris.org wrote: Hi everyone, I have a web app who is divided into a web services and a ui front end. Actually the ui is made from servlets who call a business services layers and my web services use the same business layer. But I wonder if it is a way to write a set of REST services for replacing the old web services and using these REST for the ui too. Does someone have some usefull tips or experience about that ? Thanks -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2655998 I have used Restlet in such fashion using the internal web connector and using freeMarker (or velocity) as a way to server dynamic content from the various ressources, but I found it is perhaps not the proper way to do it as you find yourself making some Rest requests uri that carry UI presentation options (example choosing one template or an other for a given ressource). So you tend to have a REST implementation of your app's ressources and a UI (server side) representation to provide to the client. In this case Resltlet don't offer you clear advantage over other server side provider (your java actuel java container, a simple ruby/python http stack like sinatra or the like). If you look at the View side (on the classical MVC) you could consider moving more ressources to the actual client using Restlet as the controled/model and making the view (controled view) be generated directly on the browser client (e.g using jQery). Then your web services side could provide a simple json RESTlet application access layer and you'll make standalone javascript page (or server side generated javascript applications) and use ajax (websockets) to talk to your Restlet App. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2656930
Re: Using a REST layer for UI and services
On 06/09/10 13:26, webp...@tigris.org wrote: Hi everyone, I have a web app who is divided into a web services and a ui front end. Actually the ui is made from servlets who call a business services layers and my web services use the same business layer. But I wonder if it is a way to write a set of REST services for replacing the old web services and using these REST for the ui too. Does someone have some usefull tips or experience about that ? Thanks -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2655998 I have used Restlet in such fashion using the internal web connector and using freeMarker (or velocity) as a way to server dynamic content from the various ressources, but I found it is perhaps not the proper way to do it as you find yourself making some Rest requests uri that carry UI presentation options (example choosing one template or an other for a given ressource). So you tend to have a REST implementation of your app's ressources and a UI (server side) representation to provide to the client. In this case Resltlet don't offer you clear advantage over other server side provider (your java actuel java container, a simple ruby/python http stack like sinatra or the like). If you look at the View side (on the classical MVC) you could consider moving more ressources to the actual client using Restlet as the controled/model and making the view (controled view) be generated directly on the browser client (e.g using jQery). Then your web services side could provide a simple json RESTlet application access layer and you'll make standalone javascript page (or server side generated javascript applications) and use ajax (websockets) to talk to your Restlet App. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2656929
Re: JMS
On 06/09/10 18:56, Fraser Goffin wrote: Are there any plans in the near term to support JMS. Those of us using Restlet in Enterprise environments often require asynchronous and highly reliable protocols offered by one of the popular messaging backbones (MQ) ?? Fraser. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2656067 you could consider using Camel as the entry point using restlet, see here : http://camel.apache.org/restlet.html or using the bean actovator pattern inside one of your reslet to invoke a direct:beanref endpoint to push a message inside a Camel route (http://camel.apache.org/direct.html) then use Camel jms endpoint to implement the push inside your message queue. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2656928
Re: restlet and comet
On 07/09/10 15:08, Maxime Bégnis wrote: Hi list, I would like to include in a Restlet application some resources to be used with the CometD(Ajax Push) framework. I didn't find any documentation or examples of use cases with Restlet on the internet. Can someone point me to a starting point, if there is one? you could take a look at the restlet page concerning the upcomming NIO connector http://wiki.restlet.org/developers/172-restlet/354-restlet.html It sound at a moment that atmosphere (https://atmosphere.dev.java.net/) (a good intro here : http://www.infoq.com/news/2008/06/grizzly-atmosphere) could be a good link to have a solid comet implementation (from the guy who wroted grizly), but there is a dependency on the servlet api (http://restlet.tigris.org/issues/show_bug.cgi?id=825) that sound to be a blocking point for restlet implementation. Atmosphere is favoring Jersey as the REST implementation for the server (so Restlet is less a priority for them I guess). (I'm sure a lot of people in this list could give you a more precise up to date information on the subject). On my side I have dropped completly the comet side of the thing, in favor of a websocket implementation outside restlet. In a schema like : Reslet application - ruby server using event machine implementing websockets - javascript client and I'm in the mixt of decoupling further the Reslet to ruby server using camel and a message queue (would love to use rabbittMQ on the ruby side, but java integration from restlet/camel is far more easier using activeMQ as AMQP is not yet in par with camel (using Qpid). Websocket as good support in modern browsers (webkit and firefox) and there is a transparent proxy (using flash) that provide the necessary implementation to Internet Explorer 7+ so it's a good bet now. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2656773
Re: JMS
On 06/09/10 18:56, Fraser Goffin wrote: Are there any plans in the near term to support JMS. Those of us using Restlet in Enterprise environments often require asynchronous and highly reliable protocols offered by one of the popular messaging backbones (MQ) ?? Fraser. you could consider using Camel as the entry point using restlet, see here : http://camel.apache.org/restlet.html or using the bean actovator pattern inside one of your reslet to invoke a direct:beanref endpoint to push a message inside a Camel route (http://camel.apache.org/direct.html) then use Camel jms endpoint to implement the push inside your message queue. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2656769
Re: Using a REST layer for UI and services
On 06/09/10 13:26, webp...@tigris.org wrote: Hi everyone, I have a web app who is divided into a web services and a ui front end. Actually the ui is made from servlets who call a business services layers and my web services use the same business layer. But I wonder if it is a way to write a set of REST services for replacing the old web services and using these REST for the ui too. Does someone have some usefull tips or experience about that ? I have used Restlet in such fashion using the internal web connector and using freeMarker (or velocity) as a way to server dynamic content from the various ressources, but I found it is perhaps not the proper way to do it as you find yourself making some Rest requests uri that carry UI presentation options (example choosing one template or an other for a given ressource). So you tend to have a REST implementation of your app's ressources and a UI (server side) representation to provide to the client. In this case Resltlet don't offer you clear advantage over other server side provider (your java actuel java container, a simple ruby/python http stack like sinatra or the like). If you look at the View side (on the classical MVC) you could consider moving more ressources to the actual client using Restlet as the controled/model and making the view (controled view) be generated directly on the browser client (e.g using jQery). Then your web services side could provide a simple json RESTlet application access layer and you'll make standalone javascript page (or server side generated javascript applications) and use ajax (websockets) to talk to your Restlet App. -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=2656782
Advice on libraries/solutions available to implement REST services on microsoft .NET framework
Hi gentlmen, I need to hook a restlet based server to a client that will be integrated on window .NET based products. I want to hook my restlet server to this client, by implementing on the latter a small REST server that will subscribe to the restlet server for events and having then the restlet server push thoses events as REST like http requests it will send for each received/generated events it handle. So having something like : (events generating/collecting systems) - my Restlet Server (and model) - REST requests for subscribed event - (.NET REST server) class - other developer code in .NET code base When talking to Microsoft developer it sound like implementing an http listener is not an easy task. The smarter one have heard about silverligthning and WCF, but they code for standard .NET business apps not silverbullet one ;-) I have absolutely no clue or advice to give to them and the only solution they come up with is to send my request using SOAP. I'm afraid I couldn't survice such an horrible step back in technology ! Do you guys have some advice, lecture and hints for me for coding a sample .NET class that would consume such a REST request and call their own onEventReceived delegated method so both them and I would fill at home ? Thanks in advance for your lumières -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447dsMessageId=1828464
Re: 1.1.0 maven
Thanks Thierry - I had forgotten about this. It has been decided to remove the pom files since the inception of the maven repositories. What's the policy w.r.t. subversion? There is no 1.1.0 folder in http:// restlet.tigris.org/svn/restlet/tags/1.1/ Are you updating subersion at the same time you update maven? Are there 2 trees? -Vincent.
Re: 1.1.0 maven
Hi Thierry, okay I see the tag now. Question: shouldn't you update buil/build.xml: It still refers to a snapshot version: #release-type: . #release-type-full: . #release-number: 0 release-type: snapshot release-type-full: Snapshot release-number: -Vincent.
Re: 1.1.0 maven
Question: shouldn't you update buil/build.xml: Imeant build.properties. -Vincent.
Re: Restlet 1.1.0 released!
we have just pushed Restlet 1.1.0 out of the door!! Darn, there goes our excuse for postponing the update from 1.0.7! Congrats to the team. I'm looking forward to playing with the new features. -vincent.
1.1.0 maven
Hello, I don't see the 1.1.0 version in the maven repository. Should we be using the SNAPSHOR version? Also, why are the poms no longer part of the distribution? Thanks, -Vincent.
Re: setting up Server (Jetty) with SSL
Hugh, I am guessing that I need to get hold of the server object some how and set the SSL key path (which i have created). I am confused as to role that Component has here. In other code i have seen the following to create a new Server instance: http://article.gmane.org/gmane.comp.java.restlet/2312 -vincent
Re: Best practices for read-only fields?
Richard, The only advice Richardson seems to offer on incoming representations is that a client should be able to fetch a representation, modify it, and PUT it back where it found it. HTTP 1.1 rev01 add the concept of partial PUT for a brielf period of time. This is from http 1.1 rev 01: 9.6.1 Partial PUT (PUT with Content-Range) A PUT method MAY supply a partial entity body specified by a Content- Range header. The PUT requests that the resource be updated or created with the partial entity-body, in a manner entirely up to the origin server. However, the origin server may indicate to caches that they may perform the same update to a cached copy. Put it was dropped in rev (02 (see http://lists.w3.org/Archives/Public/ietf-http-wg/1997OctDec/0011.html) Roy has a great explanantion here of why patching with PUT is wrong: A diff is a representation of how to get from one state to another, not a representation of either of those states. Therefore, it is always wrong to patch the resource on a PUT of a diff, as opposed to setting the resource state to the diff. (http://tech.groups.yahoo.com/group/rest-discuss/messages/ 10069?threaded=1m=evar=1tidx=1) So, yes, #3 is the only RESTful option, but as Jerome suggested, you could create new resources: PUT /itinerary/123/startDate -vincent.
Re: Best practices when Implementing acceptingRepresentations?
Hi Richard, On my project, we have two transport layers (and we also provide a Java Client): - SOAP - REST (which can return several representations of the same data). So, we used the POJO serialization/deserialization way. Since we provide a client API, we realized that our client POJOs could be slightly different than our persisted POJOs. I agree there is some redundancy, but, for example, there is no need to expose the technical id or the (Hibernate) version to the transport layer. All our client POJOs have natural keys. For some objects (mainly the exceptions), we used XSD+XSLT to generate the actual Java exceptions and their REST envelope (JAXB does not like the Exception ;-). Hope this help. -- Vincent Ricard
Re: Best practices when Implementing acceptingRepresentations?
Erik Beeson a écrit : [...] We use XStream to do all of our serialization, so we get to switch between XML and JSON for free, which is really nice. Our containers end up really cluttered with a lot of XStream related annotations (mainly @XStreamAlias and @XStreamImplicit), so separating them helps keep the data POJOs much cleaner. interesting for the input/validation, thanks for the tip! for output needs I needed to be able to let the end-user client be in charge of the output he wants for its own usage, so I'm now considering templating solution where the Rest server handle the request, build a business context (mainly a list of hased POJO) and then use a template name either implied by the client signature, or provided in the request URI to choose from. So for example I could provide an XML tailored for each client, letting the end-user choose the format he wants to eat. one other option I didn't yet fully investigated is letting this templating be done on the client side, where the context for the template engine is provided by the REST payload (have a look here : http://www.kuwata-lab.com/tenjin/ where you see that you can get in javascript more speed than velocity).
Re: advice needed for using glassfish as intermediation server to implement Restlet comet/bayeux style architecture
John D. Mitchell a écrit : On Thursday 2008.10.02, at 23:00 , Vincent Nonnenmacher wrote: [...] I'm confused... What are your dashboard clients doing that need to sustain 3 RPS (requests per second)? I.e., why do you need fast updating for a dashboard app? It's not like this is some sort of critical systems control panel (for e.g., an assembly line, nuclear power plant, medical monitoring, etc.). if you look at the breakdown of queues, having members, calls being held, active calls coming and watching agents behaviour you got that number as each one is making its own timed poll loop, so this 3 req/s is on a 'small call-center'. As we do 'distributed' queues handling on several servers, you double this when a dashboard monitor two systems. Its true however that the size of the payload will augment with the number of agents/queues with the same frequency. There's certainly absolutely no reason at all to be making separate requests for each piece of that information. I.e., you can easily compact that down to a single bulk update request or, at the very least, make each request over a single connection. yes I came already to the same conclusion (and by the way your bellow note about REST abstraction is on the same verge) in order to minimize the number of requests as long as big list chunk is easily handled as a collection to update a DOM on the client side. Rob Heittman example is on the same 'list technique' Also using queuing tricks (like the ones available on jQuery and Dojo also help without too much complexity on the client code. I came down now to 1 req/s monitoring two servers and a dozen of qeues/members. As the requests are chunked and finally displayed in a aggregated DIV tree, the match between receiving a pre-digested structure and DOM building is on par, so the event to DOM marshalling is quite natural. In terms of following multiple systems, again I'll recommend, if you really care about scaling this to lots of clients, that you add a concentrator/caching tier which would coalesce information from e.g., multiple backend services/systems/etc. for efficient use by the clients. This has so very many benefits, it's work to list them all. So, in terms of your concern about the number of connections/requests growing multiplicatively in the number of clients * systems, this approach can again compact that down into a single client connection to a concentrator/cache server and e.g., one single bulk update request. my server does exactly that on the asterisk servers side, so there only one connexion for a lot of clients to one of the server distributed 'abstraction' (in fact it is where the 'innovation' really goes ;-) But this doesn't solve the 'too much/too often' requests when using even 'subtle polling' techniques for solving the asynchronous/synchronous problem giving a close as possible 'real time' feeling. In fact the only area in telephony where customers want to feel 'real time' is the time between hearing their phone ringing on the desk and seeing who's calling (even when working in openspace, 'who's calling my buddy phone'. If you solve that subtle feeling with a quick display reaction, they will excuse a certain amount of latency in further display adjustment (like seeing that a phone goes from ringing to answer, or a queue member status been updated somewhere else). So in fact there is no need (as you pointed out so much euhhh 'precisely' ;-)) for an asynchronous refresh for ALL the client updates. BTW, a helpful way to think of the bulk requests is as a higher-level publish/subscribe model (which is basically how Rob's solution for the police works, the subscription is to the event log). The bulk update request becomes: give me every new 'event' since [the last time I asked]. On the AJAX client side, if you're going to progress beyond the 'fun demo' level, you're going to need to switch to a clean, event driven model in the client anyways to make it efficient, manageable, etc. and that will actually make it easier for the web designers, eventually. As part of that layer, your code bursts the bulk request and fires off the appropriate AJAX events to update the DOM and the UI catches up as it will. no pun intended for the 'fun demo level' indeed ;-) but I'm convinced that simple/short clear demo sample help a lot of OSS to grab end user attention as they don't have a too steep learning curve. But you're absolutly right about the fact that handling the most part of the communication/process part is the only way to deliver a 'simple/elegant' interface for him. The problem stay within the match between asynch handling inside the various server to get a consolidated abstraction and then breaking it when/by using an ajax client of a Restlet server because the only good way to 'conform' to habits is to pack them in a list, then rebuild the abstraction from such a chunked transmission and then recode an event
Re: advice needed for using glassfish as intermediation server to implement Restlet comet/bayeux style architecture
Rob Heittman a écrit : Meant to post this last night, but am on travel with intermittent connectivity. Jerome's reply makes it a bit ad hoc ... My love of REST and the Web doesn't quite extend to the use case of a large N of concurrent clients monitoring a single source of near-realtime events. To me, this is the kind of application that cries out for UDP, multicast and other low level techniques for extreme scalability with responsiveness. And a heavy client that can use these techniques. I concur to that but my mandatory business case force me to have a least an open light ajax/web client. By the way when you look at the network level where you see all phones /pbx conversation to handle Busy Lamp Field signaling for ringing, iddle and so on events, you see the exact same point (not solved by a multicast, but a standard publish/subscribe/notify pattern like e.g SIP like) But I've been in the spot of needing something like this to work over unaided HTTP in a browser for whole-product reasons. So here is a pattern I've used in practice, for a law enforcement application; it works okay and customers like it, but the design still feels forced to me -- the whole use case is not a great fit for a pure browser-based application. [] Given that HTTP/1.1 is typically used and the total size of an exchange is thrifty, many, many concurrently polling clients can be supported, especially with an NIO-based server. In my app, the poll interval is self-throttling and not deterministic; a client begins a new poll after the last poll completes, plus any configured delay. That a VERY enlightening example, thanks a lot it gave me several ideas. I'm wondering how you make your self-throttling adaptation and if the server couldn't help here but as you said it is perhaps not needed if no payload is involved when not absolutely necessary. As John said, instant updates may not be needed; a second or three may be an acceptable delay between UI updates. This design ensures that eventually every client will see every event, but there is no realtime or near-realtime guarantee. The faster/better the client computer, the closer to realtime its performance. that's right up to the point the user as an other way to see the event happening by an other mean. In the phone example, the user could hear the ring much before the 1-2 seconde delay and feel the solution is slugish because of that false sense of non reactivity. I guess if I imagine your solution, this is the same a someone seen activity on a camera just before you visually trigger its attention ? Anyway, not sure any of that is relevant to what you want to do ... if you forge ahead on the Comet path please let us know how things come out. I'm trying to use the comet implementation available inside Grizzly web server (tring not to require usage for a web container (jetty using continuation, or JSR Servlet ASR implementation). There both Dojo and a jQuery projects that implement the bayeux protocol with a clean pub/sub to a 'chanel' concept that in my opinion could be opted in in a REST world in the future and then if that work, perhaps the solution is to limit the number of DOM elements that absolutly need to be aysnchronously pushed to the web UI and use clever techniques like the one you describe for higher acceptable latencies in other part of the DOM. Thanks again for your nice description.
advice needed for using glassfish as intermediation server to implement Restlet comet/bayeux style architecture
Hi gentlemen, I'm architecturing a new opensource project around asterisk PBX and Restlet to offer a RESTFull view of an asterisk server (or cluster of *). I've got a working server and already use it in production servers for monitoring, clustering and call distribution purposes for our customers but I'm now facing architecture choices for making user interfaces for various clients technology. I've choosen first to implement an ajax inerface to it for demonstration purposes so I quickly wrote several QuickSimple samples using jQuery. But looking at the bandwith used by exchanges between client and Restlet server I quickly see the limits for this 'polling' approach (for example a simple queues management console for monitoring several asterisk servers's calls queues are around 3 request/s and even if each grab 1-5 ms of time to serve the approach will push linearly on the server as the client augment * by the polling frequency) I can quickly conclude that a generic console that will show you all your company phones status multiplied by the number of people watching them is a dead end solution (think about 500 users watching each other phones and how this scale) So I looked around for a comet implementation of this with Restlet but after following the full circle beginning with Grizzly cometd/bayeux implementation, I came to the Support asynchronous processing http://restlet.tigris.org/issues/show_bug.cgi?id=143 RFE And the thoughts about how to solve this synchronous - asynchronous dilemma using futures but when I then looked at my concern as outlined by this : (* server publishing internal events) - my server events listeners - Rest representation - Restlets - (polling synchronous ajax requests) and the ideal view of it from a bayeux enabled client outlined as this : (browser with for example dojo like bayeux client) - subscribing to 'events/changes' - Rest representation coupled with trigers events coming from my internal events listeners - my server listeners - (* server publishing internal events) where everything is asynchronous but then I loose my REST interface in the middle. Then I came with the following I would like an advice for you wise guys ;-) What if I use a staggering approach ? Where I could get this kind of separation : Glassfish as a front end for comet/bayeux interaction for synchronous operation with browser using an internal/local RESTlet connexion for getting synchronous access to the RESTfull representations So glassfish will solve the asynchronous - synchronous access to the proper RESTFull representation but access it only when the need to propagate the changes arose and do it synchronously (its like having your 'future idea' being resolved only when the representation change is needed). Is this too heavyweight or do you have get more thoughts about it in Restlet before the 1.2 Milestone ? Thanks in advance for your lumières ;-)
RE: [RFC] WadlResource, get a param value according to the description
Hi Jerôme, Sorry to answer so late, i'm a little busy :) I created the corresponding issue: http://restlet.tigris.org/issues/show_bug.cgi?id=604 Actually, the template value should be 0;service=hihi and not just hihi. Isn't it? Actually, i expected hihi, i believed ';' was a separator (the matrix separator) like '?' is the query separator. It seems I was wrong :) What do you think if we could enable the matrix separator in the template engine? (i dont know where, i dont know how). I know this separator is not part of the standard URI grammar... that's just an idea :) Best regards, -- Vincent Ricard
RE: [RFC] WadlResource, get a param value according to the description
Hi Jérôme, Does it make more sense now? Yes :) I added the support of multi-value multi-style parameters (see the attached Services.java). If you load the attached webapp, then try http://localhost:8080/my-webapp/restlet/service/0;service=hihi?service=foo You get this: 0;service=hihi hihi foo Knowing the route is /service/{service}, this means the hihi value is returned via the matrix form, _but_ the template value also contains it. Is it normal? Regards, -- Vincent Ricard sample.tgz Description: GNU Unix tar archive package com.mycompany.app; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.restlet.Context; import org.restlet.data.Form; import org.restlet.data.MediaType; import org.restlet.data.Parameter; import org.restlet.data.Reference; import org.restlet.data.Request; import org.restlet.data.Response; import org.restlet.ext.wadl.ParameterInfo; import org.restlet.ext.wadl.ParameterStyle; import org.restlet.ext.wadl.RequestInfo; import org.restlet.ext.wadl.WadlResource; import org.restlet.resource.Representation; import org.restlet.resource.StringRepresentation; import org.restlet.resource.Variant; import org.restlet.util.Series; import com.noelios.restlet.http.HttpConstants; public class Services extends WadlResource { public Services(Context context, Request request, Response response) { super(context, request, response); this.getVariants().add(new Variant(MediaType.TEXT_PLAIN)); } @Override public Representation represent(@SuppressWarnings(unused) Variant variant) { Representation rep = new StringRepresentation(getService(), MediaType.TEXT_PLAIN); return rep; } private String getService() { String s = ; for (Parameter parameter : getParams(getRequestInfo(), service)) { s += + parameter.getValue(); } return s; } /* -- */ protected RequestInfo getRequestInfo() { RequestInfo requestInfo = new RequestInfo(); requestInfo.getParameters().add(new ParameterInfo(service, false, string, ParameterStyle.TEMPLATE, some doc)); requestInfo.getParameters().add(new ParameterInfo(service, false, string, ParameterStyle.MATRIX, some doc)); requestInfo.getParameters().add(new ParameterInfo(service, false, string, ParameterStyle.QUERY, some doc)); return requestInfo; } /* -- */ protected String getParam(RequestInfo requestInfo, String parameterName) { return getParams(requestInfo, parameterName).getFirstValue(parameterName); } protected Form getParams(RequestInfo requestInfo, String parameterName) { ListParameter params = new ArrayListParameter(); for (ParameterInfo parameter : requestInfo.getParameters()) { if (parameterName.equals(parameter.getName())) { addParams(parameter, params); } } return new Form(params); } private void addParams(ParameterInfo parameterInfo, ListParameter params) { if (parameterInfo.getFixed() != null) { params.add(new Parameter(parameterInfo.getName(), parameterInfo.getFixed())); return; } if (ParameterStyle.HEADER.equals(parameterInfo.getStyle())) { params.addAll(getParamsFromForm(getHeader(), parameterInfo.getName())); } else if (ParameterStyle.TEMPLATE.equals(parameterInfo.getStyle())) { Object parameter = getRequest().getAttributes().get(parameterInfo.getName()); if (parameter != null) { params.add(new Parameter(parameterInfo.getName(), # + Reference.decode((String) parameter) + #)); } } else if (ParameterStyle.MATRIX.equals(parameterInfo.getStyle())) { params.addAll(getParamsFromForm(getMatrix(), parameterInfo.getName())); } else if (ParameterStyle.QUERY.equals(parameterInfo.getStyle())) { params.addAll(getParamsFromForm(getQuery(), parameterInfo.getName())); } else if (ParameterStyle.PLAIN.equals(parameterInfo.getStyle())) { // not yet implemented } if (params.isEmpty() parameterInfo.getDefaultValue() != null) { params.add(new Parameter(parameterInfo.getName(), parameterInfo.getDefaultValue())); } } private ListParameter getParamsFromForm(Form pForm, String pName) { ListParameter params = pForm.subList(pName); if (params == null) { params = Collections.emptyList(); } return params; } @SuppressWarnings(unchecked) protected Form getHeader() { Form form = null; SeriesParameter headers = (SeriesParameter) getRequest().getAttributes().get(HttpConstants.ATTRIBUTE_HEADERS); if (headers != null) { form = new Form(headers); } return form; } }
RE: [RFC] WadlResource, get a param value according to the description
Hi Jérome However, in this case, how do you deal with the fact that you could have several parameters with the same name but different type? Since i didn't need, i didn't think about this :-) Do you mean we can have something like this in a WADL? request param name=foo type=xs:string style=query/ param name=foo type=xs:int style=query/ /request Is it not a bit weird? BTW, when i looked to add a simple support of header, i added this little method to alway work with a Form: protected Form getHeader() { Form form = null; SeriesParameter headers = (SeriesParameter) getRequest().getAttributes().get(HttpConstants.ATTRIBUTE_HEADERS); if (headers != null) { form = new Form(headers); } return form; } Then i wondered, why could i not do this with a Template result? IMHO, it will make the life easier (only mine? ;-) if the different sources of data (such as described in the WADL: template, query, etc) could be seen as a Form (or an other common interface). Cheers, -- Vincent Ricard
Convention and booleans
Hi, I read the WADL spec and the wadl2java code (which creates the client stubs from a wadl file). The generated code seems work like that (for a boolean parameter): - if the param is true, the name is added (to the matrix or query string) (with no values); - if it is false, nothing is added. I wonder what the expected behavior for a server? Is there some spec or convention about how to handle a boolean value from a query string/matrix? For now, i do that, but i'm not sure if it's the right way: - if the query string does not contain my param, i set my internal representation to false; - if the query string contains my param, i set my reprensentation to true. Should i parse the value too? Any comments (and pointers) are welcome (and appreciate ;-) Cheers -- Vincent Ricard
[RFC] WadlResource, get a param value according to the description
Hi, Here is what i added to my WadlResource subclass (and the super class of all my resources): [see below]. I think it would be nice (in a future version) to have a similar method directly available in WadlResource. For now, this code just fulfills my needs: - it does not handle multi-valued param (but can be easily added: split into a getFirstParam and a getParam methods) - it does not handle the plain type (which requires a more complex code for the xpath stuff) - it does not handle the conversion to the correct type (as declared by the type attribute) (add a Converter object in the method signature?) - it does not handle the required attribute (we could add a WadlRequiredException in the extension or something like that) - it does not handle the header type because i dont need ;-) and because i dont know if there is an abstract layer to reach the HTTP headers without creating a strong dependency with another extension (like ServerServlet, or an other). Despite of all that, now i can just call: getParam(getRequestInfo(), service); Any comments are welcome (and anyone can reuse this code :-). --- snip --- protected String getParam(RequestInfo requestInfo, String parameterName) { ListParameterInfo parameters = requestInfo.getParameters(); for (ParameterInfo parameter : parameters) { if (parameterName.equals(parameter.getName())) { return getParam(parameter); } } return null; } protected String getParam(ParameterInfo parameterInfo) { if (parameterInfo.getFixed() != null) { return parameterInfo.getFixed(); } String value = null; if (ParameterStyle.HEADER.equals(parameterInfo.getStyle())) { // not yet implemented } else if (ParameterStyle.TEMPLATE.equals(parameterInfo.getStyle())) { Object parameter = getRequest().getAttributes().get(parameterInfo.getName()); value = (parameter == null) ? null : Reference.decode((String) parameter); } else if (ParameterStyle.MATRIX.equals(parameterInfo.getStyle())) { Parameter parameter = getMatrix().getFirst(parameterInfo.getName()); value = (parameter == null) ? null : parameter.getValue(); } else if (ParameterStyle.QUERY.equals(parameterInfo.getStyle())) { Parameter parameter = getQuery().getFirst(parameterInfo.getName()); value = (parameter == null) ? null : parameter.getValue(); } else if (ParameterStyle.PLAIN.equals(parameterInfo.getStyle())) { // not yet implemented } if (value == null) { value = parameterInfo.getDefaultValue(); } return value; } --- snip --- -- Vincent Ricard
Handler has no getMatrixAsForm method
Hi, I wonder why Handler has no getMatrixAsForm method? I mean, for consistency and convenience, i think it'd be fine to have this method. It could be have the same behavior (charset and decode values) than getQueryAsForm(). Best regards, -- Vincent Ricard
Re: Handler has no getMatrixAsForm method
Oops, sorry, i meant: why Handler has no getMatrix() method (which could call getRequest().getResourceRef().getMatrixAsForm()). Regards -- Vincent Ricard
PUT method without body entity
Hi, My application use the PUT methods to update some business objects, but some of these PUT methods do not expect an entity (the value is a string passed in the query string). RESTlet returns an HTTP 400 status. Is it a strict behavior required by the RFC? I expected the same behavior as the handlePost() method: a log trace, then a call to storeRepresentation with a 'null' param. So, is it a bug of an HTTP feature? Regards, -- Vincent Ricard
Re: WADL howto?
Hi Ralf, Does the WADL extension support this (from my understanding it does) and are there any tutorials for it? It haven't found anything yet, besides the API, and to figure it out with from API alone is a litte tiresome ;) I used the wadl component in the other way (specify the wadl file, and let WadlComponent load my Resource subclasses); but in your case, i think you just have to inherit WadlApplication to register your WadlResource subclasses (with createRoot), and for each resource override the 'describe' method. Excerpt from the javadoc: This description can be customized by overriding the #describe() and #describeMethod(Method, MethodInfo) methods. Hope this help. Regards, -- Vincent Ricard
[RFE] LogFilter.afterHandle
Hi, I read LogFilter.afterHanfle() and wondered if these 2 modifications would be better (from a performance point of view): - put the whole block into a if (this.logLogger.isLoggable(Level.INFO)) {...} - compute the duration only if needed. Regards, -- Vincent Ricard
[RFE] Engine.loadClass() should give the class name
Hi, It would be nice if Engine.loadClass() fill in the class name when it throws the ClassNotFoundException. Here, my configuration was wrong and i spent a lot of time to find the typo :-/ Is it possible? Best regards, -- Vincent Ricard
Re: URI templates and URI pattern matching in restlet
Hi Prashant I can extract request path from request object there but how will I match that REST URI with URI template(which I have hardcoded in my Restlet class) in my restlet. I'm not sure to understand your need, but the Template.match() method is not enough? Regards, -- Vincent
NPE with Wadl and ServerServlet
Hi, I'm testing the wadl support and trying to run restlet in a servlet container (from the svn source, r3631). I tried two solutions: - just declare the ServerServlet and create a restlet.xml (see the attached file) - create a custom component inheriting from WadlComponent and declare it in the web.xml (as described in the ServerServlet javadoc) with the following constructor: public RestletComponent() { super(clap://class/app.wadl); } (This is my first attempt with restlet, so i maybe forget something) It seems that wadlRep.getApplication() returns null. In the both cases, i get a NPE: java.lang.NullPointerException at org.restlet.ext.wadl.WadlApplication.init(WadlApplication.java:170) at org.restlet.ext.wadl.WadlComponent.attach(WadlComponent.java:157) at org.restlet.ext.wadl.WadlComponent.attach(WadlComponent.java:142) at org.restlet.ext.wadl.WadlComponent.attach(WadlComponent.java:171) at org.restlet.ext.wadl.WadlComponent.init(WadlComponent.java:118) at RestletComponent.init(RestletComponent.java:7) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:494) at java.lang.Class.newInstance0(Class.java:350) at java.lang.Class.newInstance(Class.java:303) at com.noelios.restlet.ext.servlet.ServerServlet.createComponent(ServerServlet.java:396) at com.noelios.restlet.ext.servlet.ServerServlet.getComponent(ServerServlet.java:643) at com.noelios.restlet.ext.servlet.ServerServlet.init(ServerServlet.java:722) at javax.servlet.GenericServlet.init(GenericServlet.java:212) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1139) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:966) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3956) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4230) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014) at org.apache.catalina.core.StandardHost.start(StandardHost.java:736) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014) at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443) at org.apache.catalina.core.StandardService.start(StandardService.java:448) at org.apache.catalina.core.StandardServer.start(StandardServer.java:700) at org.apache.catalina.startup.Catalina.start(Catalina.java:552) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433) Best regards, -- Vincent Ricard?xml version=1.0? component xmlns=http://www.restlet.org/schemas/1.1/Component; xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance; xsi:schemaLocation=http://www.restlet.org/schemas/1.1/Component; client protocols=CLAP / server protocols=HTTP / defaultHost attach targetDescriptor=clap://class/app.wadl/ /defaultHost /component
Wadl is never parsed (was: NPE with Wadl and ServerServlet)
Hi Jérôme, Thanks, the new version (r3633) does not throw NPE anymore. But my wadl is never read because wadlRep.getApplication() != null always returns false (WadlApplication, line 160). I created a sample war application to show my problem (just run mvn eclipse:eclipse to load the project with WTP, or mvn package to build the war). I guess something is wrong, but i dont find what :-) Regards, -- Vincent Ricard sample.tgz Description: GNU Unix tar archive
Re: Wadl is never parsed (was: NPE with Wadl and ServerServlet)
Ok, i found my problem. I'm sorry for the useless noise. My wadl namespace was out of date (http://research.sun.com/wadl/2006/07; instead of http://research.sun.com/wadl/2006/10;). Regards, -- Vincent Ricard
ClassCastException with a custom application
Hi, While i tried to build my own application, i get this exception (sample attached): java.lang.ClassCastException: com.noelios.restlet.ext.servlet.ServletContextAdapter at com.noelios.restlet.ext.servlet.ServerServlet.createApplication(ServerServlet.java:323) at com.noelios.restlet.ext.servlet.ServerServlet.getApplication(ServerServlet.java:594) at com.noelios.restlet.ext.servlet.ServerServlet.init(ServerServlet.java:723) at javax.servlet.GenericServlet.init(GenericServlet.java:212) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1139) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:966) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3956) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4230) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014) at org.apache.catalina.core.StandardHost.start(StandardHost.java:736) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014) at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443) at org.apache.catalina.core.StandardService.start(StandardService.java:448) at org.apache.catalina.core.StandardServer.start(StandardServer.java:700) at org.apache.catalina.startup.Catalina.start(Catalina.java:552) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433) It seems ServletContextAdapter is not an instance of ChildContext. Regards -- Vincent Ricard sample.tgz Description: GNU Unix tar archive
Re: Restlet and Velocity template location.
Stuart, I'm trying to use the TemplateRepresentation for the Velocity extension as part of a webapp, but I am having problems configuring the template location. Have you tried this: org.restlet.ext.velocity.TemplateRepresentation r = new org.restlet.ext.velocity.TemplateRepresentation(...); r.getEngine().setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, /path/to/resources); -vincent.
Re: Congratulation!“Restlet: Official Developer’s Guide to RESTful Web Applications in Java” will be out!
Title:Restlet: Official Developer's Guide to RESTful Web Applications in Java Great news! Any idea when the book will be available? I'll buy a copy for sure. -vincent.
Re: Unchecked exceptions in Resource constructors
Hi Jerome, } catch (InvocationTargetException e) { if (e.getCause() instanceof Error) { throw (Error) e.getCause(); } else { getLogger() [...] } I spoke too fast, we should also consider RuntimeExceptions: catch(InvocationTargetException e){ if (e.getCause() instanceof Error || e.getCause() instanceof RuntimeException) { throw (Error) e.getCause(); } getLogger() } -Vincent.
Re: Unchecked exceptions in Resource constructors
Hi Jerome, } catch (InvocationTargetException e) { if (e.getCause() instanceof Error) { throw (Error) e.getCause(); } else { getLogger() [...] } I spoke too fast, we should also consider RuntimeExceptions: catch(InvocationTargetException e){ if (e.getCause() instanceof Error || e.getCause() instanceof RuntimeException) { throw (Error) e.getCause(); } getLogger() } This solution doesn't work because if the cause is a RuntimeException, we can't cast it to an Error (doh!). And if we rethrow it as a RuntimeException, it'll get caught by the catch(Exception e) block of the enclosing try block. So, the solution is to throw a RuntimeException from the inner try blok, and let it bubble up from the outer try block: public Resource createResource(Request request, Response response) { Resource result = null; try { ... try { } catch(InvocationTargetException e){ if (e.getCause() instanceof Error){ throw (Error) e.getCause(); } if ( e.getCause() instanceof RuntimeException) { throw (RuntimeException) e.getCause(); } getLogger()... } } catch (RuntimeException e){ // Let unchecked exceptions bubble up throw e; } }catch (Exception e) { getLogger()... } } return result; } In short: we make sure we let all unchecked exceptions (errors runtime) flow through the method, while all checked ones (Exceptions that are not runtime) are trapped and logged. We should also document the fact that Resource constructors should never throw checked exceptions. -Vincent.
Re: Unchecked exceptions in Resource constructors
Hi Jerome, Your suggestion seems reasonable. I've applied this changed to SVN trunk (only). It is slightly different from your patch. Let me know if it works for you: Thanks. It's exactly what I needed. -Vincent.
Sending a resource URI as a form parameter
Hello, Here is what I'm trying to do: POST /colorMixer form: color1=http://www.colors.com/color/blue color2=http://www.colors.com/color/red A successful call will return 201 CREATED http://www.colors.com/clor/purple My question is how do I implement the ColorMixerResource.post(Representation) method? More exactly, how to I get the Blue and Red objects from the uris? I have a ColorResource class that has a constructor that knows how to retrieve the right color from the DB: public ColorResource(contex,request,response){ String colorCode = (String) request.getAttributes().get(color); // lookup that color code in the DB Color color = } Solution 1 == I am tempted to try to reuse that code, because when I get to this constructor, the request is already parsed, the attributes are extracted according to the template I specified for this resource. ColorMixer.post(Representation entity){ Form f = getRequest().getEntityAsForm(); String color1Uri = f.getFiestValue(color1); String color2Uri = f.getFiestValue(color2); Request request1 = new Request(color1Uri...) color1Resource = new Color1Resource(getContext(),request1, getResponse()); Color color1 = color1Resource.getColor(); // same thing for color2 ... Color result = Mixer.mix(color1,color2); // return the representation of the resulting color in the response } Solution 2 === A second approach would be to -somehow- reuse the template for the ColorResource resource and use it to parse the uris. ColorMixer.post(Representation entity){ Form f = getRequest().getEntityAsForm(); String color1Uri = f.getFiestValue(color1); String color2Uri = f.getFiestValue(color2); MapString, Object variables = new HashMapString,Object(); if (ColorTemplate.parse(color1Uri,variables) != -1){ String Color1Code = (String)variables.get(color); // get the color from the DB } // etc. } To make this work the createRoute method would have to stick the templates in the context so that they are available to resources. Neither approaches satisfies me. Yet, I'm sure there is a simple and elegant solution. Any suggestions? Thanks, -Vincent.
Re: Maven support
Jerome , should we support the legacy layout from Maven 1 or should be directly move to the better one introduced by Maven 2. Does anyone has good pointers? I don't think that too many people will want to add restlet to an existing project that is built with maven 1.x. It's more likely that the framework is being used for new projects, which should use maven 2. -vincent http://gmane.org/word.php?id=76346
Re: Maven support
Jerome, Instead of relying on a public Maven repository such as Ibiblio, we would prefer to host our own Maven repository at maven.noelios.com and control its freshness and service quality. what prevents you from controlling ibiblio's freshness? -Vincent.
Re: Question to all about visual webapps and Restlet
Hi Matthieu, Basically I've a rich client application (Flex) accessing Ah, but it's quite a different story, as the final (visual) representation is assembled on the client, not on the server. I considered each resource as being kind of a virtual web page, with one URI and one (or several if required) layouts (representations). The application accesses the required resources, and assembles them for display. So if one page displays A and B, and another page displays A, B, and C, A knows it has two layouts (a/B and A/B/C). If you later add D to the page, you'll add a third layout for A. Is that correct? An important point is that each resource includes links to all other resources it is logically linked to: the client has absolutly NO knowledge of the links between resources, it virtually navigates between them as needed. If A is linked to A and B, when the client accesses A it receives its representation, including a link to B and a link to C; Let say these resources are independent one of another (For instance if A is a weather report, B a news feed, and C your profile). Who is responsible for linking them together? Does A know it's linked to B and C, or are these associations established at a higher level? A's representation contains a link to B and C, which means the client has to GET and C, and pass their representation to the template in order to generate the page. So, do B and C's representations contain links to A? -vincent.
Re: Question to all about visual webapps and Restlet
John, I think it's helpful to think in terms of fundamental, base resources and composite, view resources. [...] For other cases, I think it makes more sense to have the facets more or less completely disjoint. The human useful, composite views may make a lot more sense to the user if they have their own naming hierarchy, etc. and just use the various, lower-level resources as services, if you will, that are managed separately. Are you saying views should be first-class resources. and GET 'lower-level' resources to assemble the page? If yes, what's the need for the lower-level resources? The ForumView resource would just retrieve the object it needs from the DB (profile and post in Jeff's example), inject them in the template and return the template's result. -vincent.
Re: Question to all about visual webapps and Restlet
I agree and would add that those lower-level resources (or core resources) could be modelled and exposed as either: - persistent POJOs (db4o, EJB3, etc.) - RESTful resources (via a separate Restlet application for example) In the second case, you could even think about a two-layer approach, where on Web Component would remotely access to an internal Core/Business Component. This way, your Core Component could be shared between several 'view' applications/components. So, say we have a page that displays a picture of an apple and a picture of an orange. When we click on either picture, we want to replace it by the text representation of the selected fruit (we we want to keep displaying the picture of the other fruit). We have 3 resources: MainPage, Apple, Orange. Apple and Orange are what you call 'low-level' resources'; the Mainpage resource is the highest abstraction. To display the main page you GET /mainPage What are the apppe's and orange's URI's like? For the apple: /mainPage?orange=pictureapple=text For the orange: /mainPage?orange=textapple=picture Is that what you had in mind? What if we want to modify the orange? Do we PUT the mainPage, passing it the Orange info? -vincent.
Re: Response Headers
Jerome, All standard HTTP headers have an equivalent class/property in the Restlet API. It was a deliberate choice to not expose those headers as first-class citizens, because we consider them as lower-level artifacts and because we want to support multiple protocols via the same API. I think this is a good candidate for a FAQ entry, as most people will instinctively look for a Response.setHeader(String name, String value) method. I struggle with this too when I first started with Restlet. -vincent.
Re: Response Headers
Maybe I'm blind, but I don't see how to set a header in a response. I need to set the Location header on a response to a POST, but I can't seem to find the right place to do that. What am I missing? response.setStatus(Status.SUCCESS_CREATED); response.setRedirectRef(request.getRootRef() + uri); -Vincent.
PatternSyntaxException when a variable is used more than once in a template
When you reuse a variable in a template (e.g. router.attach(/{p1}/{p1}/foo,MyResource.class);), you get this exception when you try to GET the URI: java.util.regex.PatternSyntaxException: Illegal octal escape sequence near index 90 /((?:[a-zA-Z0-9\-\.\_\~]|\ [ -- stuff deleted --] +\,\;\=]|\:|\@)+)/\0/foo ^ Apparently, util.regex doesn't like the '\0' you're adding to the regexp when a variable is reused. -Vincent.
Re: Getting confused
Hi Jerome, I apologize for beating that one to death, but I still have questions... It seems that the Atom Publishing Protocol spec slightly diverges from HTTP 1.1 spec on this case. I'm sorry, I quoted an early draft. The current APP draft states: When the server generates a response with a status code of 201 (Created), it SHOULD also return a response body, which if provided, MUST be an Atom Entry Document representing the newly- created resource. They went from 'MUST also return a response body' to SHOULD. So, it's now less of a divergence. This point being clarified, I'd be interested in seeing how you'd implement the following scenario: - A collection contains images and videos - When the client creates an image (by POSTing to the collection), it expects to get back a thumb nail of that image (if created successfully) in png format (the server is responsible for creating the thumbnail). [I know, it's a dumb example, for it's just for discussion's sake] Here is what the client would send to create an image: POST /collection Name: mycat.jpg Accept: image/png binary content What do CollectionResource's constructor and CollectionResource.post look like? The constructor defines the variants for a collection resource (getVariants.add(...)). Obviously, image/png isn't one of them. Therefore, CollectionResource.getPreferredVariant returns null. Now, CollectionResource.post must create an ImageResource, and return a representation of this resource by calling ImageResource.getRepresentation(Variant variant). Does does CollectionResource.post know that the preferred variant is image/png? My guess: post(...) { [..] ImageResource image = new ImageResource(...); // find the factory and client info [...] Variant v = factory.getPreferredVariant(clientInfo, image.getVariant); return image.getRepresentation(v); } It is my understanding that you'd have to follow this pattern every time you create a resource by POSTing to a collection. -Vincent.
Guard.authenticate gets executed twice
Hi, Unless I'm missing something, I believe Guard.doHandle should be changed from: public void doHandle(Request request, Response response) { switch (authenticate(request)) { case 1: // Valid credentials provided if (authorize(request)) { accept(request, response); } else { forbid(response); } break; case 0: // No credentials provided challenge(response); break; case -1: // Wrong credentials provided forbid(response); break; } } to: public void doHandle(Request request, Response response) { switch (authenticate(request)) { case 1: // Valid credentials provided accept(request, response); break; case 0: // No credentials provided challenge(response); break; case -1: // Wrong credentials provided forbid(response); break; } } Otherwise, authenticate ends up being called twice (once in the switch statement) and once by authorize() in the case statement. -Vincent.
regexps in uri patterns
Hi, It used to be possible to do: router.attach(/foo/[0-9]*, ...); From the examples, it seems that the new way is: router.attach(/foo/{id}, ...); It makes for a cleaner and more self-documented code, but I wonder if we're not losing some flexibility. For instance I could need to bind a resource to /foo/[0-9]*, and a different one to /foo/[a-z]*. This is no longer possible. -Vincent.
Re: Getting confused
Hi Jerome, Concerning Variant, maybe the name confuses you but there is a concrete need for separating it from Representation. I guess what's confusing me is the getRepresentation(Variant variant) method. I interpret id as 'get a representation from this variant'. But its actual meaning should be 'fill the representation part of this variant, if you haven't done it already in the resource's constructor'. To me, the semantic of this operation is more a 'set' than a 'get' (What I want is to set the data part of the variant): Variant.setRepresentation(Resource resource) (I believe the original design was more along those lines). The creation of a Representation instance (able to provide the content via streams/channels in addition to metadata like languages, encodings, media type, etc.) can be a costly operation, Agreed. So, the idea is that -if the representations are too expensive to build- the constructor can build empty shells (variants) as placeholders. Perfect, lazy initialization is a good thing. Now, when it's time to return the actual representation, instead of filling the shell, we have to create a new one: Representation getRepresentation(Variant variant){ if (MEDIA_TYPE.TEXT_PLAIN.equals(variant.getMediaType)){ return new StringRepresentation(...); } else { ''' } } Why would I have to create a new object to store a representation of my resource if I already created one in the constructor? Well, it's because I can't extend an object's class at runtime (From Variant to StringRepresentation), so now, what I thought was an empty representation of my resource is actually used as a type. Hence the confusion. I can now wrap my mind around this concept (although I'm still not sold on it), but it's far from obvious when you start working with the framework (you really have to read the code and spot the downcast to see how the pieces fit together). -Vincent.
Script to install a Restlet distribution into a maven2 repository
Hi all, I use this bash script to upgrade my local maven2 repository each time a new version of Restlet comes up. Some of you might find it useful. -Vincent. #!/bin/bash # # This script installs a Restlet disrtribution into a local (filesystem) # maven2 repository. # # Usage: restlet2mvn.bsh path to Restlet distribution path to local maven repository # if [ $# -le 1 ]; then echo Usage: restlet2mvn.bsh path to Restlet distribution path to local maven repository exit 1; fi RESTLET_DIST=$1 MAVEN_REPOSITORY=$2 MVN=mvn if [ ! -e $RESTLET_DIST ] then echo Restlet distribution not found: $RESTLET_DIST exit 1; fi if [ ! -e $MVN_REPO ] then echo Maven repository not found: $MVN_REPO exit 1; fi LIB_DIR=$RESTLET_DIST/lib POMS_DIR=$RESTLET_DIST/lib/poms poms=`ls $POMS_DIR/*.pom` for pom in $poms do # restlet/lib/poms/foo.pom - restlet/lib/foo.jar jar=`echo $pom | sed s/.pom$/.jar/g | sed s/poms\\\///g` if [ -e $jar ] then # Extract the group, artifact id, and version number from the POM: # We assume that the first groupId, artifactId, version tags found in the pom # contain the module's group id, artifact id, and version #. # This will break if the pom contains commented out tags: # groupIdfoo.groupId # !-- artifactIdbar/artifactId -- # artifactIdbar/artifactId # versio1.0/version group=` grep --regexp 'groupId.*/groupId' --max-count=1 $pom | sed 's/[[:space:]]*[^]*[[:space:]]*//g' ` artifact=` grep --regexp 'artifactId.*/artifactId' --max-count=1 $pom | sed 's/[[:space:]]*[^]*[[:space:]]*//g' ` version=` grep --regexp 'version.*/version' --max-count=1 $pom | sed 's/[[:space:]]*[^]*[[:space:]]*//g' ` # Now deploy the module $MVN deploy:deploy-file -DgroupId=$group \ -DgeneratePom=false \ -DpomFile=$pom \ -DartifactId=$artifact \ -Dversion=$version \ -Dpackaging=jar \ -Dfile=$jar \ -DrepositoryId=local-repository \ -Durl=file://$MAVEN_REPOSITORY fi done exit
StringIndexOutOfBoundsException
Steps to reproduce: - create a restlet app - GET http://localhost:8182// (note the two slashes). -Vincent SEVERE: Unhandled exception or error intercepted java.lang.StringIndexOutOfBoundsException: String index out of range: -11 at java.lang.String.substring(String.java:1768) at java.lang.String.substring(String.java:1735) at org.restlet.data.Reference.getRemainingPart(Reference.java:768) at org.restlet.Route.score(Route.java:419) at org.restlet.util.RouteList.getBest(RouteList.java:91) at org.restlet.Router.getNext(Router.java:295) at org.restlet.Router.handle(Router.java:391) at org.restlet.Filter.doHandle(Filter.java:107) at org.restlet.Filter.handle(Filter.java:136) at org.restlet.Router.handle(Router.java:393) at org.restlet.Filter.doHandle(Filter.java:107) at com.noelios.restlet.StatusFilter.doHandle(StatusFilter.java:87) at org.restlet.Filter.handle(Filter.java:136) at org.restlet.Filter.doHandle(Filter.java:107) at org.restlet.Filter.handle(Filter.java:136) at c
Re: Getting confused
Thanks Jerome, that helped a lot. I still need a few clarifications, though: So far so good, but what about POSTs? Should the constructor check the method type, like so: public MyBeanResource(Context context, Request request, Response response){ super(context,request,response); if (request.getMethod().equals(Method.GET)) { String name = request.getResourceRef().getLastSegment(); myBean = new MyBean(name); } else { // it's a POST - nothing to do. } } This doesn't sound right. Indeed this would be confusing. The method-based dispatching in the responsability of the caller, not the resource itself. Once the MyBeanResource instance is created, the Finder will introspect it to find the matching handle*() method based on the method name. Most of the common methods already have an implementation of handle*() on the base Resource class. My question was more 'what the constructor should do for a PUT request?' For a GET, it builds the resource (from the DB, filesystem, etc.) based on the URI. But this doesn't apply to a POST or a PUT. The constructor doesn't know the finder is building a MyResource instance to answer a PUT. In the ch7 examples, UserResource's constructor behaves like all methods were GETs: it always attempts to retrieve the username from the URI and -if it's not null- it gets it from the DB. If the request is a PUT, it should not even attempt to retrieve the resource, as it doesn't exist yet. How can the constructor decide what to do? But, how do I have access to the client's preferred variant (application/xml in this case)? This is done automatically for you in the Resource.handleGet() method. Oh, so if I want to return a representation of the object I've just created in the post/put method I have to call handleGet(): public void post(){ [...] // create the resource getResponse().setStatus(Status.SUCCESS_CREATED); getResponse().setRedirectRef(...); // return a representation of the newly created resource: handleGet(); } Isn't that a bit confusing? And what if I want to return the representation of another resource? For instance, a CAPTCHA the user must answer to confirm the creation of the resource. It that case, I'd need to to know what is the client's preferred variant. The confusion probably comes from the increased responsibility of Resource. In RC2, all the handle*() methods were implemented in the Handler. It is still a bit confusing to me that a Representation inherits from Variant. I'd tend to see the variant as an attribute of a representation (variant=type, representation=content). The fact that you have to do a downcast in Resource.getRepresentation indicates to me that something isn't quite right: public Representation getRepresentation(Variant variant) { Representation result = null; if (variant instanceof Representation) { result = (Representation) variant; } return result; } In other words, I'm not sure this hierarchy respects the Liskov substitution principle. Thanks, -Vincent.
Re: Maven support added
I've just updated the current.zip with changes to the POM artifact ID. They now closely match the JAR names as recommended here: http://maven.apache.org/guides/mini/guide-naming-conventions.html Thanks Jerome, it'll help a lot. One comment: com.noelios.restlet.pom contains the following definition: groupIdcom.noelios.restlet/groupId artifactIdcom.noelios.restlet/artifactId version1.0rc3/version I believe the artifact id should be 'restlet-impl', not 'com.noelios.restlet. -Vincent.
Getting confused
Hi, I upgraded to RC3 and am getting seriously confused. I have to rewrite most of my application's restlet-related code, and I can't figure out how I should do it. I started with Handlers, then I replaced them with Finders (along with associated Resource classes); and now. it seems like I can attach resources to a router, and that the framework will take care of the finder. My problem is that I don't understand what the Resource classes are supposed to do. Tthe tutorial and the code from the example directory are very different; I'm not sure which one I should follow. Let me give you an example. I want to create beans with: POST /bean HTTP/1.1 Host: localhost:8182 Accept: application/xml name=titi and have the server return an xml representation of the newly created object. Beans a retrieve with: GET /bean/we HTTP/1.1 Host: localhost:8182 Accept: application/xml Here is the code: public static class MyBean{ public MyBean(String name){this.name = name;} public String name; } public static class MyBeanResource extends Resource{ private MyBean myBean; public MyBeanResource(Context context, Request request, Response response){[...]} @Override public boolean allowPost() {return true;} @Override public boolean allowGet() {return true;} @Override public ListVariant getVariants(){[...]} @Override public void post( Representation entity){[...]} @Override public Representation getRepresentation(Variant variant) { [,,,]} } public void main(String[] args){ Application application = new Application() { @Override public Restlet createRoot() { Router router = new Router(getContext()); router.attach(/bean, MyBeanResource.class); return router; } }; [...] component.start(); } The finder uses reflection to build a MyResource object. So for a GET, the constructor should retrieve the approriate bean: public MyBeanResource(Context context, Request request, Response response){ super(context,request,response); String name = request.getResourceRef().getLastSegment(); myBean = new MyBean(name); } So far so good, but what about POSTs? Should the constructor check the method type, like so: public MyBeanResource(Context context, Request request, Response response){ super(context,request,response); if (request.getMethod().equals(Method.GET)) { String name = request.getResourceRef().getLastSegment(); myBean = new MyBean(name); } else { // it's a POST - nothing to do. } } This doesn't sound right. Now, the getVariants method. Is its purpose to return all the representation types the resource can have (text/plain, application/xml, etc.)?. @Override public ListVariant getVariants(){ Variant v = new Variant(MediaType.TEXT_PLAIN); ListVariant variants = new ArrayListVariant(); variants.add(new Variant(MediaType.TEXT_PLAIN); variants.add(new Variant(MediaType.APPLICATION_XML)); return variants; } The getRepresentation seems pretty straightforward: @Override public Representation getRepresentation(Variant variant) { if (variant.getMediaType().equals(...)){ return new StringRepresentation(myBean.name); } else if (variant.getMediaType().equals(...)){ return new } else { return new StringRepresentation(myBean.name); } } As for the post method I would do something like: @Override public void post( Representation entity){ // create the bean Form form = new Form(entity); String name = form.getValues(name); myBean = new MyBean(name); getResponse().setStatus(Status.SUCCESS_CREATED); getResponse().setRedirectRef(http://localhost:8182/bean/; + name); // return a representation of the newly created bean getResponse().setEntity(this.getRepresentation(???); } But, how do I have access to the client's preferred variant (application/xml in this case)? Any clarification is welcome. Thanks, -Vincent.
Re: Restlet 1.0 RC2 released
Hi Jerome, Could you share this script or the generated POMs on this bug report? http://restlet.tigris.org/issues/show_bug.cgi?id=91 Done.Ideas to improve it are welcome. -Vincent.
Re: Handlers for search urls
attach(/accounts/[0-9], new GetAccountHandler()) attach(/accounts, new SearchAccountHandler()) Yes, that's what I ended up doing. It's a good solution. Thanks. Vincent.
Re: toString shouldn't change the object's state
Thanks Jerome. 4) Caching is an important requirement that we will address later, probably at a higher level (as a CacheFilter or CacheService?). There is a RFE for it already: http://restlet.tigris.org/issues/show_bug.cgi?id=25 Could you please shed some light on the threading question? Piyush and John indicated that Request.getValue must be synchronized should we want to cache teh stringg, but I don't understand why. I must have missed something in Restlet's threading model. Thanks, -Vincent. The problem with cache invalidation for muttable objects in a multithreaded environment isn't straightforward Why would two threads access the same request? If it's the case, wouldn't we need to add proper synchronization to the getStream method anyway? public synchronized InputStream getStream() throws IOException { InputStream result = this.inputStream; this.inputStream = null; setAvailable(false); return result; }
Re: Handlers for search urls
Hi Jerome, The choice of not exposing the query string and the fragment part of the target resource URI was deliberate. The question is: is the question mark part of the query string? The reason is that the query string is often composed of a sequence of parameters (key=value) that can appear in any order while keeping the same semantics. Agreed. I wasn't trying to define a regexp on the request parameters, I was just interested in catching the question mark. I wanted to differentiate between '/accounts/123' and 'accounts?status=active'. It turns out that attach(/account/[0-9]+,..) and attach(/accounts[.]+,...) does the trick, but attach(/accounts?[.]+,...) would have been slightly more elegant. -Vincent.
Re: Handlers for search urls
Just a thought: could it be because ? is a valid regexp meta- character ( No, it's not the issue. -Vincent.
Re: Handlers for search urls
Hi Piyush, /accounts/search/less_than/1 /accounts/search/greater_than/1 /accounts/search/between/1/2 The issue I have with this approach is that it doesn't allow to mix several search criteria (balance_less_than=2000status=active). I'd like to have: 1) /accounts/1234 - retrieve an individual account 2) /accounts?balance_less_than=2000status=active -search That's why I was hoping creating my restlets like so: attach(/accounts/[0-9]+$, new GetAccountHandler()) attach(/accounts?[.]+$, new SearchAccountHandler()) would work. Now, following your idea, I could do: attach(/accounts/search?[.]+$, new SearchAccountHandler()) and access it with /accounts/search?balance_less_than=2000status=active But it kind of bothers me to have to have to specify the action twice (the http GET method and the 'search' portion of the url). and restlets that support that class because they understand the URLs .. Well, it turns out restlets only understand the base of the URLs. -Vincent.
Re: Handlers for search urls
Sean, We had a similar issue and I think this is an area where the REST philosophy is somewhat stressed. [..] We decided to make a web service, use a POST and put the criteria in the XML. Then the URI could be /accounts/search which is pretty easy to deal with. I'm not sure it stretches the REST philosophy. POSTing a search criterion makes sense if you want to cache a cursor on the server side, for instance. You could do this: POST /accounts/search balanceLesstThan=2000 status=active The serve returns: http 2001 created location:/accounts/cursor/121212 The server keeps the open cursor in the cache for a limited amount of time. You access it with: GET /accounts/cursor/121212?page=2 This is on the salesforcers.com search API works. -Vincent.
Re: toString shouldn't change the object's state
Jerome, Agreed, let's reuse the safer getValue() : String method introduced in StringRepresentation and deprecate toString(). Thanks for making the change. Why not go one steo further and have getValue cache the value? private boolean cached = false; private value = null; public String getValue() { if (!cached) { try { value = ByteUtils.toString(getStream()); cached = true; } catch (IOException ioe) { } } return value; } This way getValue, Request.getEntityAsString, etc. would always return the same result. Which is what you expect from a method with a getter-like name, and would prevent some hard-to-pinpoint bugs. -Vincent.
Re: toString shouldn't change the object's state
Is it an immutable that the getValue returns the same value for the entire lifetime of the object? I would tend to say 'yes'. else we have the added problem of invalidating the cached value etc... Sure, if we have a setValue method (or any method that affects the value), it should reset the cache. Why is that a problem? what is interesting about your example code is that you use a boolean and not a compare to null like Any specific reason why you did that ? two reasons: 1) in case -as you suggested- null is a valid value (like you,I cannot think of a good use-case, but you never know). 2) to deal with the exception. Right now the IOE is swallowed, but I imagine Jerome will want to fix that before 1.0 goes final. So we could have something like: private boolean cached = false; private value = null; private RuntimeException rte = null; public String getValue() { if (!cached) { try { value = ByteUtils.toString(getStream()); cached = true; } catch (IOException ioe) { rte = new IllegalStateException(); } } if (rte != null) { throw rte; } return value; } Just think aloud here. -Vincent
Re: toString shouldn't change the object's state
The problem with cache invalidation for muttable objects in a multithreaded environment isn't straightforward Why would two threads access the same request? If it's the case, wouldn't we need to add proper synchronization to the getStream method anyway? public synchronized InputStream getStream() throws IOException { InputStream result = this.inputStream; this.inputStream = null; setAvailable(false); return result; } -Vincent
I have extended ApplicationHelper. Now what?
How do I register it? Form reading the code, it looks like I have to override com.noelios.restlet.Factory.createHelper, but it seems wrong. Thank you. -Vincent.
Filter questions
Hi everybody, The (rather long) discussion I had on htis forum with some of you convinced me to give restlet a try and see if it'd be a good fit for our next project. I've been playing with the framework for a few days now and I hit my first snag. Here it goes: My initial configuration is: (filter1) --- router - [handler1] | |-- [handler2] Now, when a handler throws an Error, it is not caught because StatusFilter.doHandle only catches Exceptions. The second problem is that the call to the error-throwing handler never returns. So I decided to add a second filter, that has pretty much the same behavior as Status Filter, except that it catches Throwable. Here is the new configuration (see below for the code): (filter1) --- (filter2) --- router - [handler1] | |-- [handler2] But much to my surprise, filter2.doHandle is never executed (although filter2.beforeHandle gets executed). So, here are my questions: 1- how come filter2.doHandle is not executed? Does it have something to do with scorers and the fact that filter2 does not score high enough? I must admit I don't get this scoring thing. If somebody could shed some light, that'd be great. 2- How do I subclass StatusFilter to change its behaviour? I.e how do I make ApplicationHelper.start instanciate my StatusHelper class? Thanks, -Vincent. PS: I'm testing with the Simple web server. -- import org.restlet.*; import org.restlet.data.*; public class Test { public static void main(String[] args) { Container container = new Container(); container.getServers().add(Protocol.HTTP, 8182); Application application = new Application(container) { public Restlet createRoot() { // first filter Filter filter1 = new Filter(getContext()){ public void beforeHandle(Request request, Response response){ System.out.println(In filter1.beforeHandle); } }; // second filter - chain it to the first filter Filter filter2 = new Filter(getContext()){ public void beforeHandle(Request request, Response response){ System.out.println(In filter2.beforeHandle);// This method gets executed } public void dohandle(Request request, Response response){ try{ System.out.println(in filter2.doHandle); // How come we never execute this? super.doHandle(request, response); } catch(Throwable t){ t.printStackTrace(); response.setStatus(Status.SERVER_ERROR_INTERNAL); } } }; filter1.setNext(filter2); // A router with 2 handlers - chain it to the second filter Router router = new Router(getContext()); router.attach(/foo$,new Handler(){ public void handle(Request request, Response response){ response.setEntity(handler foo, MediaType.TEXT_PLAIN); } }); router.attach(/bar$,new Handler(){ public void handle(Request request, Response response){ throw new Error(boo!); //throw new NullPointerException(boo!); } }); filter2.setNext(router); return filter1; } }; container.getDefaultHost().attach(, application); try { container.start(); } catch(Exception e){ e.printStackTrace(); } } }
Re: How to compromise when designing a RESTful API?
Think about a Resource as the Object class in Java for example: anything is an Object, whether you want it or not. Yes, but objects have state *and* behaviour. All the REST articles I’ve seen so far conveniently ignore the behaviour part by carefully choosing examples where the server does not need to perform any business logic (e.g. the ATOM protocol, which is touted as the ultimate REST application). It seems to me that all these articles are saying is ‘use setters on your objects, and save the object when you’re done’. This forces me to do: rectangle.setCenterX(12); rectangle.setCenterY(34); rectangle.save(); When what I really want to do is: rectangle.translate(4,6); In conclusion, try to think in term of resources addressable by URIs and document exchanges instead of remote objects and remote method calls. The documents can be either the representations of resources or the representation of the intended state of a resource, or the entity to be processed by a processing/service resource. I interpret this as: whenever you find yourself needing a semantic richer than what setters have to offer, use the Command Pattern AND treat commands as resources. At first sight, it seems to me like turning a command into a resource is just a trick that allows you to say ‘oh no, no, no, I’m not using RPC at all! I’m a true RESTfarian, you see’. Now, a very good reason why I would want to turn a command into a command would be to guarantee idempotence. The scenario would be: client - server: POST /translateCommand server - client: 201 Created server- client: Location: /translateCommand/12 client - server: PUT transalationCommand/12 objectId45645/objected transalateX4translateX transalateY6/translateY The server records the transaction status, and simply ignores any further attempts to re-execute the transalateCommand with id #12. But if I start going down this path, I’ll want to use the same mechanism for creating objects. So, to create a rectangle, I no longer POST a Rectangle resource but PUT CreateRectangleCommand, get transaction id, and PUT the command with the rectangle id, and the X, Y info. So, trying to think in RESTfarian terms let me to confine POSTs to the creation of commands. Back to banging my head on the wall.. Thank you all for your great input, it really in my journey towards a more RESTful world. -Vincent.
Re: How to compromise when designing a RESTful API?
Okay, so this brings up the question of how pure do you want to be? More exactly, it brings the question of what am I gaining by trying to be 100% ‘pure’? To be much more pure, you'd do this in stages: PUT to e.g.: /authinfo/account/123/transfer and get back a transfer transaction ID. Then, you'd do the specific transfer: POST to e.g.: /authinfo/account/123/transfer/≤transactionID amount=$1,000.23 targetAccount=456789 and you'd get back a confirmation code or whatever as the body of the 200 response (if the 200 response isn't enough all by itself). Yes, I’m starting to see that (although it seems to me that you have your POSTs and PUTs backward: shouldn’t you use a POST to create the transfer transaction, and a PUT to send the tx details?). Then, you can always do a get to e.g.: /authinfo/acount/123/transfer/≤transactionID to e.g., get the details of that transfer. And what if I want to close all accounts that have been inactive for at least a year, without retrieving them one by one? Would this approach: POST /account/?inactivityPeriod=365 Host: myserver.com Content-Length: XXX actionclose/action be more appropriate than this one? POST /account/ Host: myserver.com Content-Length: XXX actioncloseInactive/action inactivityPeriod365/inactivityPeriod Um, er, isn't that just something that is done on the server? Is this for an admin client instead of a user client? It was just an example. So, yes, you can imagine it’s for an admin console. Following the approach you suggested, I guess it would look like this: Client - server: POST /authinfo/accountJanitor server - client: 201 Created server- client: Location: /accountJanitor/12 client - server: PUT accountJantor/12 inactivityPeriod365/inactivityPeriod As I’ve mentioned in my response to Jerome, I think this solution has the merit of helping make all requests idempotent. My problem was that I would most likely want to extend this mechanism to resources creation as well; i.e. instead of POSTing a account resource, I would POST a tx resource and PUT the account details in this tx. -Vincent.
Re: Re: How to compromise when designing a RESTful API?
I think the approach you're advocating forces the client to know way more about the server than it should, and to make it do way more work than it has to. POST /transfer/account/123 Host: myserver.com Content-Length: XXX toAccount456/toAccount amount300/amount It *seems* like you're passing an action, but IMO what you're actually doing is turning the action into a resource, which is very powerful. That resource has a unique address, a state that can be transferred, and is only manipulated with our four magic verbs. You can even make it asynchronous by posting a transaction and polling for its status later at the resource's URL. http://tech.groups.yahoo.com/group/rest-discuss/message/6561 So, you're suggesting that a URL like /transferMoney/account/123 is indeed a resource, especially if it is used in conjunction with a transaction (as Benjamin suggested in his post): client - server: POST /transferMoney server - client: created; location: http://myserver.com/transferMoney/789 client - server: PUT /transferMoney/789 fromAccount123/fromAccount toAccount456/toAccount amount300/amount The fact that the transfer happens inside a transaction is a server concern; the client does not need to have this knowledge. Plus, it forces the client to make 2 calls instead of one. And what if I want to close all accounts that have been inactive for at least a year, without retrieving them one by one? Would this approach: If you don't want to retrieve them one by one I think you can do the same thing, invert an action into a resource with something like: GET /accounts/?inactivityPeriod=365 You get back a set of account URLs: accounts account link=/account/1234 / account link=/account/1235 / account link=/account/1236 / /accounts Which maybe you can POST to an 'account closing' resource: POST /account-closer accounts account link=/account/1234 / account link=/account/1235 / account link=/account/1236 / /accounts Here are the issues I see with this approach: - you force the server to expose an extra search API - the result set could be huge. - increased traffic between the client and the server - you still have a RPC-sounding resource (the accountCloser) Or whatever. I'm pretty sure this isn't gospel, but it makes sense to me, and I think demonstrates the power of the 'resource' abstraction. H, it seems to me that you're bending to API to make it fit the REST model, to the point where you end up breaking the abstraction layers (client knows/does too much). I'm a REST newbie, so I might very well change my mind and adopt your point of view, but -at this point- I'm still unconvinced by this 'action as a resource' approach. -Vincent.
Re: How to compromise when designing a RESTful API?
Thanks John for the great feedback. On the source account, you'd initiate a transfer with the arguments being the target account and the amount. The result on success would be that specific transfer's ID. Ah, but you're not saying how you 'initiate a transfer'. It's one of the questions I'm struggling with. It could be: POST /account/123 Host: myserver.com Content-Length: XXX action Transfer/action toAccount456/toAccount amount300/amount Or: POST /transfer/account/123 Host: myserver.com Content-Length: XXX toAccount456/toAccount amount300/amount The problem I have with the first approach is that I'm still passing an action, i.e. doing some kind of RPC. My understanding is that in a 'pure' RESTful API the only way to specify the action is via the HTTP method (get,post,put,delete). The second solution seems even worse as it mixes the action with the resource. You authenticate and then post to the account's close. So, same approach: POST /account/123 Host: myserver.com Content-Length: XXX actionclose/action Again, this smells like RPC to me. And what if I want to close all accounts that have been inactive for at least a year, without retrieving them one by one? Would this approach: POST /account/?inactivityPeriod=365 Host: myserver.com Content-Length: XXX actionclose/action be more appropriate than this one? POST /account/ Host: myserver.com Content-Length: XXX actioncloseInactive/action inactivityPeriod365/inactivityPeriod You might want to look at the Atom protocol for a good example. I reviewed this protocol, but it seems to me that --with Atom- the entire business logic is run on the client, letting the server act as a simple data repository. In that case it's easy to have a 100% RESTful with no traces of RPC. Thanks, -Vincent.
How to compromise when designing a RESTful API?
Hi all, Sorry for the rather long post,but after reviewing all the available REST literature, I still have no answer to my rather philosophical question. I understand that adopting a RESTful model means I have to think in terms of manipulating addressable resources instead of thinking in terms of function calls. Great, but what do you do with operations you absolutely can't refactor according to this model? Specifically, operations that involve more than one resource, and operations that require some extra business logic (other than CRUD operation on the resource itself). An example of the first type of operations would be money transfer: you want to transfer money from account A to account B. If I were to adhere strictly to the REST philosophy, I would either: 1)decrement A, submit A with a PUT; increment B, submit B with a PUT; and manage the recovery process from the client should one operation fail. 2)Create a MoneyTransferOrder object (fromAccount, toAccount,amount)and save it with a POST. The former is -of course- a non-starter. The latter is just a way of disguising an RPC call; I think it violates the REST principle in the sense that the MoneyTransferOrder resource is defined for the sole purpose of passing parameters to server-side service, and cannot be retrieved later (i.e. it's not really a resource). An example of the second type of operations would be the closeAccount operation. Maybe I want to send a notification to a manager every time an account is closed. Again, I see two options: 1)set the isClosed proprty to True and save with a PUT. On the server, I would have to diff the account with the value in the database, this would allow me to detect that the account has been closed, and send the notification. 2)Create a CancellationOrder object, and save it with a POST The problem with the first approach is that the server has to guess what operation the client intended to complete. The second approach suffers from the same RPC-in-disguise problem mentioned before. Conclusion? Well, my conclusion is that a RESTful architecture is particularly well suited for applications where the entire business logic is done on the client and the server acts only has a data repository (e.g. del.icio.us). For other applications, you'll have to leave with the fact that you may have maybe 30% of your calls that are in fact RPC calls -i.e. a POST where you pas the operation's name parameters. That's -from what I saw- how the upcoming.org API is designed. What do you Restfarians think? Am I missing the boat on this one? Thanks, -Vincent.