RE: Response from POST

2011-03-08 Thread Vincent Fazio
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

2011-02-14 Thread Paul Vincent Craven
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

2010-11-02 Thread Vincent Nonnenmacher
 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 ?

2010-09-20 Thread Vincent Nonnenmacher
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 ?

2010-09-20 Thread Vincent Nonnenmacher
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

2010-09-13 Thread Vincent Nonnenmacher
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

2010-09-13 Thread Vincent Nonnenmacher
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

2010-09-13 Thread Vincent Nonnenmacher
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

2010-09-13 Thread Vincent Nonnenmacher
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

2010-09-13 Thread Vincent Nonnenmacher
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

2010-09-09 Thread Vincent Nonnenmacher
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

2010-09-09 Thread Vincent Nonnenmacher
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

2010-09-09 Thread Vincent Nonnenmacher
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

2010-09-09 Thread Vincent Nonnenmacher
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

2010-09-08 Thread Vincent Nonnenmacher
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

2010-09-08 Thread Vincent Nonnenmacher
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

2009-04-20 Thread Vincent Nonnenmacher
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

2008-10-29 Thread Vincent

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

2008-10-29 Thread Vincent
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

2008-10-29 Thread Vincent

 Question: shouldn't you update buil/build.xml:

Imeant build.properties.

-Vincent.



Re: Restlet 1.1.0 released!

2008-10-28 Thread Vincent

 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

2008-10-28 Thread Vincent
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

2008-10-22 Thread Vincent
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?

2008-10-21 Thread Vincent
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?

2008-10-14 Thread Vincent Ricard
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?

2008-10-14 Thread Vincent Nonnenmacher

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

2008-10-10 Thread Vincent Nonnenmacher

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

2008-10-10 Thread Vincent Nonnenmacher

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

2008-10-02 Thread Vincent Nonnenmacher

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

2008-09-30 Thread Vincent Ricard
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

2008-09-23 Thread Vincent Ricard
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

2008-09-22 Thread Vincent Ricard
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

2008-09-09 Thread Vincent Ricard
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

2008-08-28 Thread Vincent Ricard
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

2008-08-27 Thread Vincent Ricard
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

2008-08-27 Thread Vincent Ricard
Oops, sorry, i meant:
why Handler has no getMatrix() method (which could call
getRequest().getResourceRef().getMatrixAsForm()).

Regards
-- 
Vincent Ricard



PUT method without body entity

2008-08-22 Thread Vincent Ricard
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?

2008-08-21 Thread Vincent Ricard
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

2008-08-20 Thread Vincent Ricard
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

2008-08-20 Thread Vincent Ricard
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

2008-08-13 Thread Vincent Ricard
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

2008-08-12 Thread Vincent Ricard
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)

2008-08-12 Thread Vincent Ricard
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)

2008-08-12 Thread Vincent Ricard
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

2008-08-12 Thread Vincent Ricard
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.

2008-02-27 Thread Vincent
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!

2008-02-21 Thread Vincent

 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

2007-09-21 Thread Vincent
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

2007-09-21 Thread Vincent

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

2007-09-19 Thread Vincent
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

2007-08-27 Thread Vincent
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

2007-04-24 Thread Vincent
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

2007-04-24 Thread Vincent
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

2007-04-13 Thread Vincent
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

2007-04-12 Thread Vincent
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

2007-04-12 Thread Vincent

 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

2007-02-13 Thread Vincent

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

2007-02-11 Thread Vincent


 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

2007-01-24 Thread Vincent
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

2007-01-23 Thread Vincent
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

2007-01-23 Thread Vincent
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

2007-01-19 Thread Vincent
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

2007-01-19 Thread Vincent
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

2007-01-18 Thread Vincent
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

2007-01-18 Thread Vincent
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

2007-01-17 Thread Vincent

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

2007-01-16 Thread Vincent


 
 
 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

2007-01-16 Thread Vincent
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

2007-01-11 Thread Vincent
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

2006-11-07 Thread Vincent
 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

2006-11-05 Thread Vincent
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

2006-11-05 Thread Vincent
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

2006-11-05 Thread Vincent

 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

2006-11-03 Thread Vincent
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

2006-11-03 Thread Vincent
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

2006-11-03 Thread Vincent
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

2006-11-03 Thread Vincent

 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

2006-11-03 Thread 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;
} 


-Vincent


I have extended ApplicationHelper. Now what?

2006-10-31 Thread Vincent
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

2006-10-27 Thread Vincent
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?

2006-09-18 Thread Vincent
 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?

2006-09-18 Thread Vincent
 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?

2006-09-17 Thread Vincent

 
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?

2006-09-16 Thread Vincent
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?

2006-09-15 Thread Vincent
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.