Re: HEAD not well supported?
Hi all, The refactoring based on this discussion is done in SVN trunk. See this issue for few more details: http://restlet.tigris.org/issues/show_bug.cgi?id=361 I've also updated the 1.1 snapshot at: http://www.restlet.org/downloads/1.1/current.zip Best, Jerome
Re: HEAD not well supported?
Hi Sumit, So what's the difference between a Handler and a Finder? The Finder class still has the same role. It can find and instantiate target handlers. As Resource is a subclass of Handler, it can also instantiate target resources like today. The flow of the request would go through the following after this refactoring. Server - Component - Application - Router - Finder - Handler - Resource - Domain Object No, it stil directly goes from Finder to Resource for the reason above. I'm trying to understand the separation-of-concern/value-add that each layer offers. The extraction of Handler as a super class is just a way to clarify roles and abstraction level changes. Handler is closer to the Uniform interface, which is a lower-level API. Resource is closer to REST view of things, and closer to your domain objects. Again, the changes proposed are fully backward compatible with your existing code. If we ever need to more radically change this design, we would do it in a major 2.0 release. But we are not there yet :) Hope this clarifies, Jerome
Re: HEAD not well supported?
Jerome Louvel contact at noelios.com writes: Hi all, Thanks for the quality of the feed-back. I feel like I'm now grasping all aspects of the problem and can propose a solution: 1) Split the Resource class into an abstract Handler class and a Resource subclass Hi Jerome, What is the motivation of the Handler class? I have no problem with it, I just want to understand. Is it merely to be explicit about lower level API and higher level, or is there more to it? 4) Resource offers a higher-level API that, as Tim said, is easier to use to map to domain objects, handles content negotiation, conditional methods. - handleGet() is implemented based on the variants property, the getPreferredVariant() and getRepresentation(Variant) methods - handlePost() is implemented by calling an acceptRepresentation(Representation) method to match the REST/HTTP 1.1 terminology and have less parallel names. - handlePut() is implemented by calling a storeRepresentation(Representation) method to match the REST/HTTP 1.1 terminology and have less parallel names. - handleDelete() is implemented by calling a deleteAll() or delete() or removeAll() or remove(). I like the idea of mapping well to the REST terminology. Feed-back welcome. It seems alright but there's enough there that I hesitate to endorse whole- heartedly without trying it out. That's when I usually can establish my comfort level best. Best regards, Jerome Sean
RE: HEAD not well supported?
Hi Sean, What is the motivation of the Handler class? I have no problem with it, I just want to understand. Is it merely to be explicit about lower level API and higher level, or is there more to it? Exactly, the goal is to clarify the separation between the lower API and higher one. The Handler class will be in org.restlet and Finder won't have any direct knowledge of the Resource class. It could be used directly for those preferring to work at this level. In term of Javadocs, that will also make things much easier to explain. It seems alright but there's enough there that I hesitate to endorse whole- heartedly without trying it out. That's when I usually can establish my comfort level best. Fair enough, I've got most of the changes done locally now. I will try to commit them in the coming days. Best regards, Jerome
Re: HEAD not well supported?
Sean Landis sean.landis at gmail.com writes: Jerome Louvel contact at noelios.com writes: Hi all, Thanks for the quality of the feed-back. I feel like I'm now grasping all aspects of the problem and can propose a solution: 1) Split the Resource class into an abstract Handler class and a Resource subclass Hi Jerome, What is the motivation of the Handler class? I have no problem with it, I just want to understand. Is it merely to be explicit about lower level API and higher level, or is there more to it? So what's the difference between a Handler and a Finder? The flow of the request would go through the following after this refactoring. Server - Component - Application - Router - Finder - Handler - Resource - Domain Object I'm trying to understand the separation-of-concern/value-add that each layer offers. Thanks. Sumit
RE: HEAD not well supported?
Hi all, Thanks for the quality of the feed-back. I feel like I'm now grasping all aspects of the problem and can propose a solution: 1) Split the Resource class into an abstract Handler class and a Resource subclass 2) Handler only works at the lower API level and specifies only the handle*() and allow*() methods. The default behavior is very basic: - nothing is allowed - handleHead() redirects to handleGet() and this is clearly documented - handleOptions() use the updateAllowedMethods() to automatically update the Response based on the available allow*() methods and their return value. - handleDelete(), handleGet(), handlePost() and handlePut() set the status to SERVER_ERROR_INTERNAL 3) Handler has convenience methods getApplication(), getLogger(), the context, request and response properties. It also has a new allowHead() method which is invoked by the Finder. 4) Resource offers a higher-level API that, as Tim said, is easier to use to map to domain objects, handles content negotiation, conditional methods. - handleGet() is implemented based on the variants property, the getPreferredVariant() and getRepresentation(Variant) methods - handlePost() is implemented by calling an acceptRepresentation(Representation) method to match the REST/HTTP 1.1 terminology and have less parallel names. - handlePut() is implemented by calling a storeRepresentation(Representation) method to match the REST/HTTP 1.1 terminology and have less parallel names. - handleDelete() is implemented by calling a deleteAll() or delete() or removeAll() or remove(). See REST terminology here: http://roy.gbiv.com/pubs/dissertation/rest_arch_style.htm#sec_5_2_1_2 See HTTP 1.1 methods terminology here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html 5) Also, in order to provide a equivalent of the Handler.allow*() methods, I propose to map them (for GET, POST, PUT and DELETE only): - Handler.allowGet()- Resource.readable property - Handler.allowPost() - Resource.modifiable property - Handler.allowPut()- Resource.modifiable property - Handler.allowDelete() - Resource.modifiable property That's it, Finder would also require a few minor changes to only know about the Handler class. This would be backward compatible. Feed-back welcome. Best regards, Jerome -Message d'origine- De : Michael Terrington [mailto:[EMAIL PROTECTED] Envoyé : dimanche 14 octobre 2007 01:25 À : discuss@restlet.tigris.org Objet : Re: HEAD not well supported? Tim Peierls wrote: There's a false parallel here that I don't think should be encouraged by providing parallel names. getRepresentation takes a Variant argument, handleGet does not; post takes a Representation argument, handlePost does not. If anything, I'd argue for names that were *less* parallel, e.g., add instead of post, and remove instead of delete. +1 for less parallel names, especially if handle* is moved to Finder. The only difficulty I see is coming up with a good name for post. Add to me corresponds to remove, so perhaps createResource? Regards, Michael.
Re: HEAD not well supported?
Tim Peierls wrote: There's a false parallel here that I don't think should be encouraged by providing parallel names. getRepresentation takes a Variant argument, handleGet does not; post takes a Representation argument, handlePost does not. If anything, I'd argue for names that were *less* parallel, e.g., add instead of post, and remove instead of delete. +1 for less parallel names, especially if handle* is moved to Finder. The only difficulty I see is coming up with a good name for post. Add to me corresponds to remove, so perhaps createResource? Regards, Michael.
Re: HEAD not well supported?
Tim Peierls tim at peierls.net writes: There's a false parallel here that I don't think should be encouraged by providing parallel names. getRepresentation takes a Variant argument, handleGet does not; post takes a Representation argument, handlePost does not. If anything, I'd argue for names that were *less* parallel, Breaking a false parallel would be fine too. As log as it is no more misleading than the current ;-)
Re: HEAD not well supported?
I have always been a bit unsure of which methods to override for the different verbs/methods, always considering it a bit of a nuisance and a potential put-off for new adopters (I'm carrying on about the potential problems to new restlet implementors, but it's only because I believe it's one of the factors needed to become a successful framework). But looking at this discussion, I've started wondering if this isn't a problem in the design of Resources. I have found myself having to look at the code several times when implementing a new Resource, just to make sure I know what the class I'm extending (usually Resources, although I sometimes make my own base resources for applications and inherit from them) is actually doing. According to Java Practices web site, this is one of the points for considering composition instead of subclassing [1]. I still don't know if this explicitly relates to this problem, but it definetly seems like we have a case of coupling of the implementation of Resource and its subclasses. I don't know if I'm off the map here, but just had a thought and wanted to share with the people with the know-how. Regards, Kyrre [1]http://www.javapractices.com/Topic72.cjp --- Tim Peierls [EMAIL PROTECTED] wrote: On 10/11/07, Chuck Hinson [EMAIL PROTECTED] wrote: allowPut(), allowPost(), allowDelete(), allowGet() handlePut(), handlePost(), handleDelete(), handleGet() put(), post(), delete(), getRepresentation() - eh? what? The lack of symmetry there is jarring - it leads people to go looking for the get() method and when they can't find it, they're confused. It depends on how they approach the documentation. The javadoc class comment for Resource presents these in the reverse order; it isn't jarring if you first encounter getVariants, getRepresentation, put, post, and delete, *then* find out that there is a lower level of handle* methods (that you might not have to deal with at all, if you're lucky). It *is* slightly awkward that you have to use the lower level allow* methods to control whether your higher-level overrides will be used. Maybe the constructor could take an argument to handle some common cases with, say, an EnumSet? I think two things need to happen. First, the documentation for handlePut(), handlePost(), handleDelete() and handleGet() needs a whole lot more detail making it plain what exactly they do. More precisely, what they do by default (i.e., implement the higher-level API of getVariants, getRepresentation, post, put, delete) *and* what they should do if overridden, e.g., a warning that overriding handleGet without calling super.handleGet can cause any overridden getRepresentation and getVariants methods to be ignored (unless your handleGet calls getPreferredRepresentation, say). And second, yes, I think put(), post() and delete() and getRepresentation() need to be renamed. While doPut(), doPost(), doDelete() and doGet() are OK, I think I'd prefer processPut(), processPost(), processDelete() and processGet() - but anything that makes it clear that they are at the same level of processing is fine. There's a false parallel here that I don't think should be encouraged by providing parallel names. getRepresentation takes a Variant argument, handleGet does not; post takes a Representation argument, handlePost does not. If anything, I'd argue for names that were *less* parallel, e.g., add instead of post, and remove instead of delete. Resource is the place where the uniform interface hits the rich interface of your domain objects. It's entirely appropriate (and convenient!) to have an intermediate API (getVariant, getRepresentation, put, post, and delete) to help ease the transition between them. --tim Kyrre Kristiansen ___ Yahoo! Answers - Got a question? Someone out there knows the answer. Try it now. http://uk.answers.yahoo.com/
Re: HEAD not well supported?
Hi all, Thanks for sharing your experience. This is very valuable feed-back and I want to address these issues to this core class in release 1.1 if possible/necessary. To try to clarify, I was initially hesitant to call getRepresentation(Variant) just get(Variant) due to potential confusion with the Javabeans naming, especially because we also need a way to get the variants available. Having both a get(Variant) and a getVariants() method seemed confusing to me. So, I dediced to keep the uniform methods in Resource via the handle*() methods (see Resource.handleHead(), handleOptions(), etc.) and to provide good default implementations. So, handleGet() does a getVariants() then a getRepresentation(Variant) on the best matching variant. handleHead() delegates to handleGet(), handlePost() calls post(Representation), etc. The current approach I'm following for 1.1 is to try to move those Resource.handle() methods to the Finder class and only keep the higher level methods in Resource (getRepresentation, getVariants, post, put, delete, etc.). It could also clarify things by renaming post(Rep.) to postRepresentation(Rep.) to be more consistent with getRepresentation(Variant) namine and to reduce the confusion with lower-level Uniform handle* methods. What do you think? What is your ideal design for the Resource class? Best, Jerome 2007/10/11, Chuck Hinson [EMAIL PROTECTED]: On 10/10/07, Sean Landis [EMAIL PROTECTED] wrote: [...] We have about a dozen people writing web services using Restlet. Although head is confusing, I'd say we experience more confusion over the fact that GET is a 'special case'. That is, there's no get(), but instead you must use getRepresentation(). So far, every single developer here has stumbled on this and required explanation. I'm afraid I can't give a rationale, I just tell them that's the way it is. Sean +1 I've had the same experience with my group, and like Sean, I am at a loss as to how to explain why it has to be this way. At this point, i don't have a suggestion for how to resolve this, but I do think it violates the principle of least surprise (in a sort of roundabout way), and probably should have some effort devoted to determining whether this approach is worth the cognitive overhead it imposes. --Chuck
RE: HEAD not well supported?
Hi Sean, I think *Representation is problematic: headRepresentation()? I understand your concerns with get(Variant), getVariant(). A colleague of mine pointed out that conceptually, merely using post(), get(), etc., is like encroaching on a global name space. He suggested (and I'm comfortable with), doPost(), doGet(), doHead(), doDelete(), doPut(), and doOptions(). The 'do' has the effect of taking the names out of the global name space...conceptually. I agree, but what do you think about the fact that we already have the handleGet, handlePost, handleHead or handleOptions right in the Resource class? Do you think that handleHead() should call a doHead() method? What would be the added value? In case of handleGet() we provide a default implementation based on the getVariants() and getRepresentation(Variant) methods in order to provide a default support for content negotiation. Same for handleHead() which in 99% of the case is just a GET with no entity sent back on the wire. The handleOptions() also has a default implementation which is based on the alloww* methods available that return true. If you don't want to use content negotiation, you could directly override the handleGet(), handleHead() methods. Doesn't it cover your needs? Best regards, Jerome
Re: HEAD not well supported?
Jerome Louvel contact at noelios.com writes: ... It could also clarify things by renaming post(Rep.) to postRepresentation(Rep.) to be more consistent with getRepresentation(Variant) namine and to reduce the confusion with lower-level Uniform handle* methods. What do you think? What is your ideal design for the Resource class? I think *Representation is problematic: headRepresentation()? I understand your concerns with get(Variant), getVariant(). A colleague of mine pointed out that conceptually, merely using post(), get(), etc., is like encroaching on a global name space. He suggested (and I'm comfortable with), doPost(), doGet(), doHead(), doDelete(), doPut(), and doOptions(). The 'do' has the effect of taking the names out of the global name space...conceptually. Sean
Re: HEAD not well supported?
On 10/11/07, Jerome Louvel [EMAIL PROTECTED] wrote: Hi Sean, I think *Representation is problematic: headRepresentation()? I understand your concerns with get(Variant), getVariant(). A colleague of mine pointed out that conceptually, merely using post(), get(), etc., is like encroaching on a global name space. He suggested (and I'm comfortable with), doPost(), doGet(), doHead(), doDelete(), doPut(), and doOptions(). The 'do' has the effect of taking the names out of the global name space...conceptually. I agree, but what do you think about the fact that we already have the handleGet, handlePost, handleHead or handleOptions right in the Resource class? Do you think that handleHead() should call a doHead() method? What would be the added value? In case of handleGet() we provide a default implementation based on the getVariants() and getRepresentation(Variant) methods in order to provide a default support for content negotiation. Same for handleHead() which in 99% of the case is just a GET with no entity sent back on the wire. The handleOptions() also has a default implementation which is based on the alloww* methods available that return true. If you don't want to use content negotiation, you could directly override the handleGet(), handleHead() methods. Doesn't it cover your needs? allowPut(), allowPost(), allowDelete(), allowGet() handlePut(), handlePost(), handleDelete(), handleGet() put(), post(), delete(), getRepresentation() - eh? what? The lack of symmetry there is jarring - it leads people to go looking for the get() method and when they cant find it, they're confused. I think two things need to happen. First, the documentation for handlePut(), handlePost(), handleDelete() and handleGet() needs a whole lot more detail making it plain what exactly they do. As the documentation stands right now (1.0), it's not even clear that handleGet() will ultimately call getRepresentation(). And handlePut, handlePost and handleDelete appear to do nothing more than call put,post or delete respectively - even though the code shows that there's a lot more going on. And second, yes, I think put(), post() and delete() and getRepresentation() need to be renamed. While doPut(), doPost(), doDelete() and doGet() are OK, I think I'd prefer processPut(), processPost(), processDelete() and processGet() - but anything that makes it clear that they are at the same level of processing is fine. I've puposely avoided head and options because they're less well-known, but the do*() and process*() patterns seem to cover them just fine. And if you don't want handleHead() being a one-liner with a call to doHead(), make it clear in the docs that handleHead() actually calls doGet(). Besides, I think the number of people who will be looking for a head() or doHead() method will be significantly smaller than the number of people looking for get() or doGet(). (And just how many cases are there where you'd want to override the default behavior of head anyway?) --Chuck
Re: HEAD not well supported?
Erik Hetzner erik.hetzner at ucop.edu writes: At Mon, 8 Oct 2007 17:35:00 + (UTC), Sean Landis sean.landis at gmail.com wrote: [...deleted...] I'd say that Restlet meets the requirements of the spec and that's good. Although I still think it would be better to leverage Uniform entirely and it seems awkward to me that HEAD is an exception. My understanding of REST is that HEAD is part of the uniform interface and therefore should be supported in the same way, and to the same extent as the rest of the HTTP methods. I was very surprised when HEAD did not conform to the programming model in place for the uniform interface and I suspect others would be too. I don’t understand what you mean here by uniform interface. Uniform interface in REST refer to inter-application semantics, not intra-application. And it doesn’t, to my understanding, mean that HEAD GET must have identical semantics, rather that the semantics of a GET or HEAD request be the same for all resources. Am I misunderstanding you here? I don't know if Jerome's comment clarified so I'll follow up. The Resource class partially supports methods that map to a uniform interface (GET,PUT, POST, DELETE, HEAD, OPTIONS). The confusion is that, although there is put(), post(), and delete(), there is no head() (or options() or get() for that matter). There is an allowGet() method, but no get(), which seems even more strange. OPTIONS seems to have been entirely left out. (BTW, I am using p. 97 of RESTful Web Services as my definition of the uniform interface). My point is that the internal implementation of the uniform interface ought to be consistent. The head thing is very confusing because, not only is there no head() but there is behind-the-scenes magic that removes the content. (Based on what's been stated about curl behavior, it sounds like there are cases where content might be desired?) We have about a dozen people writing web services using Restlet. Although head is confusing, I'd say we experience more confusion over the fact that GET is a 'special case'. That is, there's no get(), but instead you must use getRepresentation(). So far, every single developer here has stumbled on this and required explanation. I'm afraid I can't give a rationale, I just tell them that's the way it is. Sean
Re: HEAD not well supported?
On 10/10/07, Sean Landis [EMAIL PROTECTED] wrote: [...] We have about a dozen people writing web services using Restlet. Although head is confusing, I'd say we experience more confusion over the fact that GET is a 'special case'. That is, there's no get(), but instead you must use getRepresentation(). So far, every single developer here has stumbled on this and required explanation. I'm afraid I can't give a rationale, I just tell them that's the way it is. Sean +1 I've had the same experience with my group, and like Sean, I am at a loss as to how to explain why it has to be this way. At this point, i don't have a suggestion for how to resolve this, but I do think it violates the principle of least surprise (in a sort of roundabout way), and probably should have some effort devoted to determining whether this approach is worth the cognitive overhead it imposes. --Chuck
Re: HEAD not well supported?
At Mon, 8 Oct 2007 17:35:00 + (UTC), Sean Landis [EMAIL PROTECTED] wrote: Regarding my previous comments regarding a test using curl; it appears curl is hung up on the fact that content length has a value and there is no entity. I did determine that Restlet does remove the content. Sorry for being misleading on that point. It does appear that curl is wrong here. I have filed a bug report at http://sourceforge.net/tracker/index.php?func=detailaid=1810273group_id=976atid=100976 You can obtain correct behavior by using the -I/--head option instead of -X HEAD, which is good to know. I'd say that Restlet meets the requirements of the spec and that's good. Although I still think it would be better to leverage Uniform entirely and it seems awkward to me that HEAD is an exception. My understanding of REST is that HEAD is part of the uniform interface and therefore should be supported in the same way, and to the same extent as the rest of the HTTP methods. I was very surprised when HEAD did not conform to the programming model in place for the uniform interface and I suspect others would be too. I don’t understand what you mean here by uniform interface. Uniform interface in REST refer to inter-application semantics, not intra-application. And it doesn’t, to my understanding, mean that HEAD GET must have identical semantics, rather that the semantics of a GET or HEAD request be the same for all resources. Am I misunderstanding you here? best, Erik Hetzner ;; Erik Hetzner, California Digital Library ;; gnupg key id: 1024D/01DB07E3 pgpa7495zhgap.pgp Description: PGP signature
Re: HEAD not well supported?
Jerome Louvel contact at noelios.com writes: Hi all, I'm a bit late in the discussion it seems :) Let me try to explain how the support for HEAD was designed in Restlet. Following the definition of HEAD from the HTTP spec [1], I got convinced that HEAD was only a special GET and nothing more: The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. In order to fulfill this requirement, the framework expects you (Resource and any Restlet/Filter/etc.) to return the exact same response as you would for the similar GET request. The trick is that at the HTTP server connector level, we never send back the response's entity content for HEAD requests. Regarding my previous comments regarding a test using curl; it appears curl is hung up on the fact that content length has a value and there is no entity. I did determine that Restlet does remove the content. Sorry for being misleading on that point. I'd say that Restlet meets the requirements of the spec and that's good. Although I still think it would be better to leverage Uniform entirely and it seems awkward to me that HEAD is an exception. My understanding of REST is that HEAD is part of the uniform interface and therefore should be supported in the same way, and to the same extent as the rest of the HTTP methods. I was very surprised when HEAD did not conform to the programming model in place for the uniform interface and I suspect others would be too. Sean
RE: HEAD not well supported?
Hi all, I'm a bit late in the discussion it seems :) Let me try to explain how the support for HEAD was designed in Restlet. Following the definition of HEAD from the HTTP spec [1], I got convinced that HEAD was only a special GET and nothing more: The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. In order to fulfill this requirement, the framework expects you (Resource and any Restlet/Filter/etc.) to return the exact same response as you would for the similar GET request. The trick is that at the HTTP server connector level, we never send back the response's entity content for HEAD requests. However, we do need the full Representation because some metadata are not part of the Variant information per se. I know in Restlet 1.0 the Variant class do have the size property but that was a mistake that we fixed in version 1.1 (trunk) by moving the property down to the Representation class (subclass of Variant). The same was done for the Expiration Date, ModificationDate and Tag properties. Also, the Finder class calls the Resource.allowGet() method for both GET and HEAD requests as there is no reason (following the HTTP spec intent) to differentiate GET and HEAD request in this regard. I'm still convinced that current design is appropriate. I would even go further by removing the Resource.handleHead() method and make the Finder class call handleGet() directly instead. Still, I'm always open for discussion! Best regards, Jerome [1] http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 -Message d'origine- De : news [mailto:[EMAIL PROTECTED] De la part de Sean Landis Envoyé : vendredi 5 octobre 2007 21:43 À : discuss@restlet.tigris.org Objet : Re: HEAD not well supported? In Summary... It sounds like folks are in agreement that HEAD is not properly supported but I haven't heard from Jerome or Thierry, etc. What do you guys think?
Re: HEAD not well supported?
At Sat, 6 Oct 2007 18:40:36 +0200, Jerome Louvel [EMAIL PROTECTED] wrote: Hi all, I'm a bit late in the discussion it seems :) Let me try to explain how the support for HEAD was designed in Restlet. Following the definition of HEAD from the HTTP spec [1], I got convinced that HEAD was only a special GET and nothing more: The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. In order to fulfill this requirement, the framework expects you (Resource and any Restlet/Filter/etc.) to return the exact same response as you would for the similar GET request. The trick is that at the HTTP server connector level, we never send back the response's entity content for HEAD requests. So during the lifecycle of a HEAD request we should never get a call to the write/getStream/getChannel/toString methods of a Representation? If so, a lazy initialization of representation content should be possible. However, we do need the full Representation because some metadata are not part of the Variant information per se. I know in Restlet 1.0 the Variant class do have the size property but that was a mistake that we fixed in version 1.1 (trunk) by moving the property down to the Representation class (subclass of Variant). The same was done for the Expiration Date, ModificationDate and Tag properties. Looking at the code, I expected that Variant had all those properties to allow for it to be sufficient for a HEAD request, so I was confused that HEAD would use a representation; but this makes sense. Also, the Finder class calls the Resource.allowGet() method for both GET and HEAD requests as there is no reason (following the HTTP spec intent) to differentiate GET and HEAD request in this regard. I'm still convinced that current design is appropriate. I would even go further by removing the Resource.handleHead() method and make the Finder class call handleGet() directly instead. […] Not my place, perhaps, but I am agreed. best, Erik ;; Erik Hetzner, California Digital Library ;; gnupg key id: 1024D/01DB07E3 pgpzsSzGTaVM2.pgp Description: PGP signature
Re: HEAD not well supported?
In Summary... It sounds like folks are in agreement that HEAD is not properly supported but I haven't heard from Jerome or Thierry, etc. What do you guys think?
Re: HEAD not well supported?
So is HEAD too obscure to garner any interest? Sean
Re: HEAD not well supported?
John D. Mitchell jdmitchell at gmail.com writes: On 10/3/07, Sean Landis sean.landis at gmail.com wrote: So is HEAD too obscure to garner any interest? I think it's probably a good default to have allowHead == true and default to having handleHead() call handleGet() but head should be fully supportable as you say. FWIW, John That would be a good solution. Backward compatible too. Sean
Re: HEAD not well supported?
Sean, I agree that HEAD should be supported. Just for the sake of discussion, however, I personally don't find HEAD all that interesting in comparison with Conditional GETs. I mean, when does the client ever just want to see if a resource has changed (or exists) without actually retrieving a representation of said resource? That's probably a pretty fringe use case, like some client that's trying to ping a resource. Generally, if it makes sense to call HEAD, it usually would make more sense to call GET conditionally, thus saving a hit. I guess HEAD would be useful too if you're not able to send an Etag or Last-Modified date with the representation and the client uses some sort of custom caching mechanism. But, that's not obviously as ideal as using the well supported built-in HTTP caching mechanisms. Oh well, Adam Sean Landis wrote: So is HEAD too obscure to garner any interest? Sean
Re: HEAD not well supported?
The main reason I've used it is to fetch content-length and make any necessary provisions (check storage space, warn user, etc.) on the client side before fetching the representation. In this case you definitely don't want the whole GET response coming at ya. - Original Message - From: Adam Taft [EMAIL PROTECTED] To: discuss@restlet.tigris.org Sent: Wednesday, October 3, 2007 4:07:22 PM (GMT-0500) America/New_York Subject: Re: HEAD not well supported? Sean, I agree that HEAD should be supported. Just for the sake of discussion, however, I personally don't find HEAD all that interesting in comparison with Conditional GETs. I mean, when does the client ever just want to see if a resource has changed (or exists) without actually retrieving a representation of said resource? That's probably a pretty fringe use case, like some client that's trying to ping a resource. Generally, if it makes sense to call HEAD, it usually would make more sense to call GET conditionally, thus saving a hit. I guess HEAD would be useful too if you're not able to send an Etag or Last-Modified date with the representation and the client uses some sort of custom caching mechanism. But, that's not obviously as ideal as using the well supported built-in HTTP caching mechanisms. Oh well, Adam Sean Landis wrote: So is HEAD too obscure to garner any interest? Sean
Re: HEAD not well supported?
Rob Heittman wrote: The main reason I've used it is to fetch content-length and make any necessary provisions (check storage space, warn user, etc.) on the client side before fetching the representation. In this case you definitely don't want the whole GET response coming at ya. Ya, OK. I like that. That's a very good use case. I can definitely agree, though it's obviously not traditional with a web browser, but more for automated clients. Of course, if we could rewrite the HTTP spec, pie in the sky it could be a conditional get header. I.e. If-Smaller-Than or some such thing. Or, maybe an Accept-Size header. That'd be neat. :) Adam
Re: HEAD not well supported?
At Mon, 1 Oct 2007 19:28:09 + (UTC), Sean Landis [EMAIL PROTECTED] wrote: I was implementing HEAD on a resource and couldn't figure out how to do it so I looked at the source for Resource.handleHead() and was surprised to see it calls handleGet(). My understanding of HEAD is that it provides all but the entity. That seems to imply that that getRepresentation() needs to check what method is used and special case HEAD somehow. That is awkward and inconsistent with the rest of the method handling paradigm. One solution is to provide allowHead() and head(). It might make sense to implement head() by calling getRepresentation() but this approach doesn't require it and fits better with the current method handling style. I don’t understand what the issue is here? Can you not override handleHead? Why should you special case getRepresentation? The representation should be the same. Presumably (correct me if I’m wrong, Restlet authors) when sending a response to a head request back to the client the server simply won’t make a call to get the actual content of the representation. In almost every way the response to the HEAD request should be the same to a GET, so it makes sense to share the logic. Also, intuitively allowHead is a bit redundant, since any resource that allows a GET really should allow a HEAD. best, Erik Hetzner pgpBRvwZrLpJV.pgp Description: PGP signature
Re: HEAD not well supported?
Erik Hetzner erik.hetzner at ucop.edu writes: I don’t understand what the issue is here? Can you not override handleHead? Yes you could but there's already a programming model for dealing with HTTP methods. One could argue handle*() methods could be final for example. Why exclude HEAD from that model? Why should you special case getRepresentation? Because HEAD shouldn't necessarily return a representation. The representation should be the same. No, a very common use case is to use HEAD to get meta-data about a resource to decide whether to call GET. For example, if the representation could be extremely large. Presumably (correct me if I’m wrong, Restlet authors) when sending a response to a head request back to the client the server simply won’t make a call to get the actual content of the representation. In almost every way the response to the HEAD request should be the same to a GET, so it makes sense to share the logic. Are you saying there's some place in Restlet where the entity is striped out in the case of HEAD? You might be right, although I didn't see it. Regardless, that makes unreasonable assumptions about the intent for HEAD. Also, intuitively allowHead is a bit redundant, since any resource that allows a GET really should allow a HEAD. That was John's point which I agree with. Default is true. Sean best, Erik Hetzner
Re: HEAD not well supported?
Erik Hetzner erik.hetzner at ucop.edu writes: Are you saying there's some place in Restlet where the entity is striped out in the case of HEAD? You might be right, although I didn't see it. Regardless, that makes unreasonable assumptions about the intent for HEAD. I don’t know; it just seems to me that the place for the optimization which doesn’t call the code that returns the content of the response when we have a HEAD instead of a GET belongs there, not in a special case in your Resource. Here's an interesting follow-up. I have a resource that only implements GET and returns Ok. As the code implies, a HEAD request will do just like GET. When I run: curl --request head my-url It blocks until timeout and then prints: curl: (18) transfer closed with 2 bytes remaining to read So it seems the esteemed tool, curl, totally expects HEAD to not return any content. Sean
Re: HEAD not well supported?
At 11:37 PM + 10/3/07, Sean Landis wrote: Here's an interesting follow-up. I have a resource that only implements GET and returns Ok. As the code implies, a HEAD request will do just like GET. When I run: curl --request head my-url It blocks until timeout and then prints: curl: (18) transfer closed with 2 bytes remaining to read So it seems the esteemed tool, curl, totally expects HEAD to not return any content. Interesting. It may be that cURL is simply following the spec. From the RFC for HTTP 1.1: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 (or for the purist, section 9.4 in http://www.ietf.org/rfc/rfc2616.txt :-): The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. Would this also imply that the correct HTTP Status code to be returned from a HEAD request should be 204, corresponding in the Restlet framework to something like getResponse().setStatus( Status.SUCCESS_NO_CONTENT )? That type of response is described in the Restlet Javadocs, with some language borrowed from the RFC's formal description, as: The server has fulfilled the request but does not need to return an entity-body (for example after a DELETE), and might want to return updated metainformation. Aron Roberts Information Services and Technology . 2195 Hearst University of California, Berkeley, CA 94720-4876 USA [EMAIL PROTECTED] . +1 510-642-5974 . fax 510-643-5385 http://purl.org/net/aron
Re: HEAD not well supported?
Aron Roberts wrote: The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. Would this also imply that the correct HTTP Status code to be returned from a HEAD request should be 204, corresponding in the Restlet framework to something like getResponse().setStatus( Status.SUCCESS_NO_CONTENT )? NO! The whole point of HEAD is to emulate a GET request, except without returning the message body. You don't need to send 204 because, by definition, HEAD already means no content. A call to HEAD should return _exactly_ the same headers as the same call to GET. Adam
Re: HEAD not well supported?
At Wed, 3 Oct 2007 19:39:10 -0700, Aron Roberts [EMAIL PROTECTED] wrote: In the message Re: HEAD not well supported?, dated 10/3/07, Adam Taft wrote: NO! The whole point of HEAD is to emulate a GET request, except without returning the message body. You don't need to send 204 because, by definition, HEAD already means no content. That makes sense: why return a status code indicating explicitly that no content is to be returned, since that may falsely imply that content in the entity body is sometimes allowed? In that case, then, a status code of 200 would seem to be the only appropriate success response from an HTTP HEAD request. Status codes 201 through 203 appear to be inappropriate to HEAD requests, as well. To be pedantic: the status code is NOT part of the message headers, and not then part of the metainformation which should be the same in a HEAD as in a GET, per 2616. But I certainly can’t think of a good reason to have a different status code for a HEAD from a GET. A call to HEAD should return _exactly_ the same headers as the same call to GET. True. Responses to HEAD requests should return the same set of HTTP headers as responses to GET requests, except for the empty entity body. As a slight refinement, however, responses to HEAD requests should not always return the range of status codes appropriate to GET requests. There are certain HTTP status codes are only appropriate to a specific HTTP method, or a subset of those methods. Specifically, there are some status codes that are appropriate to be returned in response to GET requests but not in response to HEAD requests. Could you point these status codes out to me? I can’t figure out which ones you might mean. best, Erik Hetzner ;; Erik Hetzner, California Digital Library ;; gnupg key id: 1024D/01DB07E3 pgpF6BQICFgBm.pgp Description: PGP signature