RE: Maven support added
Hi Vincent, This page indicates that the artifactId should be "the name of the jar without version." http://maven.apache.org/guides/mini/guide-naming-conventions.html Also, I've checked the Ibiblio repository and found many variants for naming: http://www.ibiblio.org/maven/ I think I would prefer to stick the current IDs based on JAR names, unless this is plain wrong or very annoying for users. Best regards, Jerome > -Message d'origine- > De : news [mailto:[EMAIL PROTECTED] De la part de Vincent > Envoyé : mercredi 17 janvier 2007 00:46 > À : discuss@restlet.tigris.org > Objet : Re: Maven support added > > > > > > > > > I've just updated the current.zip with changes to the POM > artifact ID. They > > now closely match the JAR names as recommended here: > > http://maven.apache.org/guides/mini/guide-naming-conventions.html > > > > Thanks Jerome, it'll help a lot. > > One comment: > > com.noelios.restlet.pom contains the following definition: > > com.noelios.restlet > com.noelios.restlet > 1.0rc3 > > I believe the artifact id should be 'restlet-impl', not > 'com.noelios.restlet. > > -Vincent. >
RE: Getting confused
Hi again, Let me answer inline: > I upgraded to RC3 and am getting seriously confused. Oh oh :) > I have to rewrite most of my application's restlet-related > code, and I can't > figure out how I should do it. The major change should be regarding Handlers. In most cases you should be able to completely remove them as their equivalent Finder is now more dynamic and able to instantiate target Resources based on a given class. > 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. Perfect. > 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. Currently the Tutorial stops short of explaining how to use resources. I have a task to add a new section for RC3. This is long overdue. There are new examples available, especially in the org.restlet.example.book.rest.ch7 package that should provide better guidance for now. > 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. OK. Just a side note, maybe a PUT would be more appropriate here. > Beans a retrieve with: > GET /bean/we HTTP/1.1 > Host: localhost:8182 > Accept: application/xml OK. > 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 List getVariants(){[...]} > @Override public void post( Representation entity){[...]} > @Override public Representation getRepresentation(Variant > variant) { [,,,]} > } One remark: allowGet() returns true by default so you don't have to override it in your case. Also, getVariants() has a good default implementation and shouldn't be overriden IMO. I should probably make it final to prevent confusion. It is better to update the list of variants from the constructor instead, because if getVariants() is invoked several times it can be costly to recreate the list multiple times. > 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(); > } Perfect. If you convert it to use PUT, you also also change to URI to "/bean/{beanId}" and retrieve the "beanId" value in the request's attributes map. > 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); > } Here you should add those lines at the end: getVariants().add(new Variant(MediaType.TEXT_PLAIN); getVariants().add(new Variant(MediaType.APPLICATION_XML)); Then, you can remove your overriden getVariants() method. > 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. For example, handleGet() provides support for content negotiation based on the getVariants() and getRepresentation() methods. The handlePost() methods relies on the post() method, the handlePut() on the put() method, etc. As a writer of a Resource subclass, you should only have to override the post(Representation entity) method to support POST methods. > Now, the getVariants method.
Re: Getting confused
Jerome Louvel noelios.com> writes: > In order to make your redirection more portable, you can do this instead: > > getResponse().setRedirectRef(getRequest().getRootRef() + "/bean/" + name); > Hi Jerome, I guess now you have the start of the RC3 tutorial on resources... ;-) thanks it was very useful. In the same way that the Restlet framework provides a design supporting URI->Resource "mapping", would it also make sense to provide a design for generating a resource URI, i.e. a Resource->URI mapping? There are situations where one wants to redirect to a single resource from more than one place and it would be very nice to define the Resource->URI mapping declaratively and simply redirect to this Resource instance. The resource redirection would generate the URI automatically under the covers. Maybe a combination of a URI template and an abstract Resource API allowing it to expose any number of key/values used to generate a final URI? -- yuri
Errors in Eclipse workspace
Jerome, fyi: two issues I found recreating my restlet workspace in Eclipse: - MANIFEST.MF error due to empty com.noelios.restlet.ext.jmx java package in the jmx project - Absolute path to db4o jars in org.restlet.example thanks, -- yuri
RE: Errors in Eclipse workspace
Hi Yuri, Thanks for reporting those glitches, they are now fixed in SVN. Best regards, Jerome > -Message d'origine- > De : news [mailto:[EMAIL PROTECTED] De la part de Yuri de Wit > Envoyé : mercredi 17 janvier 2007 16:37 > À : discuss@restlet.tigris.org > Objet : Errors in Eclipse workspace > > Jerome, > > fyi: two issues I found recreating my restlet workspace in Eclipse: > - MANIFEST.MF error due to empty com.noelios.restlet.ext.jmx > java package in the > jmx project > - Absolute path to db4o jars in org.restlet.example > > thanks, > > -- yuri > >
RE: Getting confused
Hi Yuri, > Hi Jerome, I guess now you have the start of the RC3 tutorial > on resources... > ;-) thanks it was very useful. Indeed! Actually this list is also a great starting point when I want to extend the FAQ pages. > In the same way that the Restlet framework provides a design > supporting > URI->Resource "mapping", would it also make sense to provide > a design for > generating a resource URI, i.e. a Resource->URI mapping? Another common need is to dynamically insert URIs into a result representation. > There are situations where one wants to redirect to a single > resource from more > than one place and it would be very nice to define the > Resource->URI mapping > declaratively and simply redirect to this Resource instance. > The resource > redirection would generate the URI automatically under the covers. I have already thought about this but the biggest problem is that this mapping isn't 1-1 as the same resource (class) can be mapped from several URIs. > Maybe a combination of a URI template and an abstract > Resource API allowing it > to expose any number of key/values used to generate a final URI? First, there is always the Template class available. It can be manually instantiated with a URI template and called by a model or a request/response pair to generate a URI. Also, with the latest changes, the Resource class expects three parameters at construction time: a Context, a Request and a Response. They become properties on the instance that could be leveraged to support a "generateUri(String uriTemplate)" method. I have just added this method as well as a new variable for the Request.rootRef property in the list of predefined variables on Template. As a result you will be able to write: myRes.generateRef("{o}/bean/{beanId}"); Note the {o} variable to insert the root reference. The list of variables is available (minus the new "o" one of course) at: http://www.restlet.org/docs/api/org/restlet/util/Template.html Best, Jerome
Struggling with recent changes
I seem to have missed something fundamental regarding the recent changes. It now appears one must create a Resource to handle the dispatching of post, etc. We have several web services that previously dispatched to a Handler that implemented handlePost. I am unclear what to do with this Resource requirement. It seems, at least for us, the complexity of using Restlet has increased dramatically. Please tell me I'm missing something. Sean
Re: Getting confused
Thanks Jerome, that helped a lot. I still need a few clarifications, though: > > So far so good, but what about POSTs? Should the constructor > > check the > > method type, like so: > > > > public MyBeanResource(Context context, Request request, > > Response response){ > > super(context,request,response); > > if (request.getMethod().equals(Method.GET)) { > > String name = request.getResourceRef().getLastSegment(); > > myBean = new MyBean(name); > > } else { > > // it's a POST - nothing to do. > > } > > } > > This doesn't sound right. > > Indeed this would be confusing. The method-based dispatching in the > responsability of the caller, not the resource itself. Once the > MyBeanResource instance is created, the Finder will introspect it to find > the matching handle*() method based on the method name. Most of the common > methods already have an implementation of handle*() on the base Resource > class. My question was more 'what the constructor should do for a PUT request?' For a GET, it builds the resource (from the DB, filesystem, etc.) based on the URI. But this doesn't apply to a POST or a PUT. The constructor doesn't know the finder is building a MyResource instance to answer a PUT. In the ch7 examples, UserResource's constructor behaves like all methods were GETs: it always attempts to retrieve the username from the URI and -if it's not null- it gets it from the DB. If the request is a PUT, it should not even attempt to retrieve the resource, as it doesn't exist yet. How can the constructor decide what to do? > > But, how do I have access to the client's preferred variant > > (application/xml in > > this case)? > > This is done automatically for you in the Resource.handleGet() method. Oh, so if I want to return a representation of the object I've just created in the post/put method I have to call handleGet(): public void post(){ [...] // create the resource getResponse().setStatus(Status.SUCCESS_CREATED); getResponse().setRedirectRef(...); // return a representation of the newly created resource: handleGet(); } Isn't that a bit confusing? And what if I want to return the representation of another resource? For instance, a CAPTCHA the user must answer to confirm the creation of the resource. It that case, I'd need to to know what is the client's preferred variant. > > The confusion probably comes from the increased responsibility of Resource. > In RC2, all the handle*() methods were implemented in the Handler. It is still a bit confusing to me that a Representation inherits from Variant. I'd tend to see the variant as an attribute of a representation (variant=type, representation=content). The fact that you have to do a downcast in Resource.getRepresentation indicates to me that something isn't quite right: public Representation getRepresentation(Variant variant) { Representation result = null; if (variant instanceof Representation) { result = (Representation) variant; } return result; } In other words, I'm not sure this hierarchy respects the Liskov substitution principle. Thanks, -Vincent.