Discussing Carrot vs. Orange
Carrot Vs Orange discusses the benefits, drawbacks, and arguments for or against Pie Api approaches "HTTP using GET/POST to a single URI" (Carrot) vs. "HTTP using the REST Architectural Style" (Orange or simply REST).
"405 Method Not Allowed" on default Apache/PHP configuration
Regarding, "Apache/2.0.40 PHP/4.2.2 RedHat/8.0: default configuration, requesting PUT atom.php 405 Method Not Allowed"
[AsbjornUlsberg] But with Apache properly configured, won't PHP allow it then? It's also important that the PHP user has proper rights in the file system, as PUT and DELETE requires both read and write privileges in the folder that is PUT'ed or DELETE'd on. GET and POST only requires read privileges.
[KenMacLeod] The context is the whether the atom.php script itself can accept GET/PUT/DELETE/POST methods, not whether Apache can support PUT/DELETE to various files in the surrounding directories. In this case, this result was obtained within the same directory where atom.cgi, a shell script, works just fine with GET/PUT/DELETE/POST. See also the clarification added to the "Platform support of PUT and DELETE" in CarrotVsOrange.
[AsbjornUlsberg] Ok, I misunderstood the context.
Problems with web hotels that can't be administered (properly)
[TomasJogin] What if one uses a web hotel provider and can't/may not configure Apache "properly" for ones own specific needs? Is this problem going to be ignored?
[AsbjornUlsberg] Well.. I think this only matters if the popularity and adoption of Atom depends on it to be solved. If Atom needs to work on todays poorly administered web hotels, virtual accounts etc., to even be used by more than those developing the format, it's a problem. If Atom will be used anyhow, it can be a pressure to get ISP's to configure the web servers correctly. I would like to get Atom in a position where users could say "Hey, don't you support Atom?" and administrators would blush because their web hotels didn't... But it's probably just Utopian.
[AsbjornUlsberg] I have a web hotel (which I pay for) and can get my ISP to administer as I want. People who don't pay for their hotels might have much more restrictions, but are they really that important to include in the API support? They can support Atom without supporting the API, can't they? I don't want two API's (one POST/GET and one POST/GET/PUT/DELETE) and I don't want only one that isn't RESTful.
[KenMacLeod] Tomas' question and two answers copied to "The argument against using PUT and DELETE" in CarrotVsOrange. Please check that and see if they sufficiently capture the issue. Update or expand as necessary.
[TimBray] I hate religious approaches. I strongly favor an HTTP API whereby you use GET to get things and POST for all modifications, since this recognizes the reality that in fact all updates (add/change/delete) are going to be routed through the publishing system, and that's what you're really updating. The only virtue of the multi-verb approach here is that it's more religiously correct. It will be harder to implement in a conventional web server, and the increased effort buys no benefits that I can detect.
-
[MarkBaker] There is actually a RESTful means of doing all mutations via POST, and I'd be all for it except for one little problem; HTTP doesn't support it (it doesn't have mandatory extensions, nor extended intention declarations, and doing so requires both). If we want a RESTful HTTP API, actions MUST be separated into different HTTP verbs. There's nothing religious about that. Ken's even demonstrating that the implementation can be quite clean, and I'm not aware of any libraries that don't parse the method for you and make it available to be used for dispatch.
-
[Arien] This page's title clearly indicates that dicussion on this page is restricted to RESTful API's. You favor something that doesn't use a multi-verb nor a multi-URI approach, so maybe one of the RPC pages suits your fancy. (Which is cool and all that, but discussing that shouldn't be done here.)
[JeremyGray] I hadn't voted on this issue thus far because I'm not currently working on relevant software, but the "single endpoint" choice resonated with me even before Tim's comment pushed me the rest of the way. Each option has its pros and cons (as well as coolness factor), but even at the cost of being a bit less RESTful there are definitely implementational benefits to be offered on the server-side by using a single URI and pure GET/POST, without even bringing up down-the-road issues like similarity to and resonance with other message-passing and/or RPC mechanisms, directory services, etc.
[KenMacLeod] As TimBray indicates, RESTful implementations often, but not always, use a single piece of code to route requests through. I'm working on examples and a deeper reply, but a quick question is: can you expand on what "implementational benefits" there are in using the same CGI in a RESTful manner vs. a GET/POST manner?
-
[Arien] A RESTful API does not use a single base URI. The underlying implementation might use a single piece of code requests for various resources get routed through. This discussion is on the API, not the underlying implementation.
-
[TimBray] Suppose we do an API with just GET and POST through a single URI. I guarantee that, given an Apache server, I can implement that API in the course of an afternoon, without looking at any documentation, in a simple CGI, or in PHP, or whatever; and I guarantee that there is a huge number of people who could do the same thing in the same afternoon. I have no idea how I'd catch DELETE and PUT transactions on each and every entry URI; It's possible Apache does this, but the knowledge is not widely distributed. And furthermore, if the resource is the publication, it's perfectly appropriate to change its state via POST to the publication's URI. The arguments for using DELETE and PUT are based on loyalty to the RESTian religion, not on an engineering basis. If somebody can provide one technical advantage of using DELETE and PUT I'd like to see it; I haven't yet. This is supposed to be a technical, not a religious, discussion.
-
[KenMacLeod] (Updated) The above example (atom.cgi) took far less than an afternoon to write and uses basic CGI techniques. It took greater time to learn more XSLT so the RESTful example itself could be easier to present (and I still needed seperate stylesheets to do it). The technical advantage is that it is much, much simpler and shows, as an implementation, virtually every need of the API except queries and sequentially created (POSTed) entries. That includes entries, templates, static files, and introspection. Comments would typically require POSTing for sequential creation.
-
[Arien] Again, this is not the place to be discussing if a RESTful API is desired. The discussion here assumes it is and focuses on what it would look like. If you want to discuss the advantages and disadvantages of a RESTful approach, please do so on another page. Now, a technical discussion is based on fact, whereas a religious discussion is based on mere beliefs (necesitated by lack of fact). Saying that you "have no idea how [you] catch DELETE and PUT transactions on each and every entry URI" to deal with the implementation of a RESTful API and then using this lack of fact on your part as an argument is definitely not helping. Anyway, Apache's mod_rewrite can change the way URIs get mapped to the filesystem ("rewriting of URLs") based on such things as REQUEST_METHOD. Enjoy.
-
[MikeDavies] Both ways are possible with Perl and PHP.
[JeremyGray] Ken, my recollection of comments made previously by others on the wiki is that many people may not have the ability to handle things like PUTs and DELETEs and/or CGI behind an unlimited set of URIs. I have my own servers and can implement whatever I want, so I'm not one of the people in that situation, and as such it may be best for someone else to comment on it further. From my own perspective, it may be beneficial to use a single endpoint so that the behaviour and mechanism jives better with systems that are dependent on (or better served by) the use of a single well-known endpoint (e.g. publishing, management, and lookup of endpoints via directory services).
-
[KenMacLeod] Many (most? all?) of the comments about people not having the ability to use PUTs and DELETEs have quickly proven to be partly or fully wrong -- some to the point that if the comments were correct those same implementations wouldn't be able to use POST either. I'd love to see a wiki page dedicated to summarizing the status.
-
[JeremyGray] On the point of "ability", as much as the purist in me might like to see how an ideal RESTful API would turn out, TimBray has made some good comments highlighting that the issue does go beyond a basic yes/no ability to implement such an API, and has highlighted the need to be pragmatic in order to minimize barriers to entry both conceptual and technical. On the need for summarization, I hear ya! I've frankly been unable to keep up with / keep track of all of the various comments and updates made across the wiki related to this topic, especially when comments aren't as clear as I might like with regards to the kind of permutations I mention in my "three polls" comment below. Speaking of which, I would be interested in any comments / corrections you might in that regard.
-
[JeremyGray] Okay, I'm back from a fresh catch-up and re-read of RestEchoApiOneUriForEachEntry and RestEchoApiPutAndDelete, and I'm actually now less certain than I was previously. Having said that, I think I'm going to have to stick with the pragmatic option for the time being.
[JeremyGray] Based on your "same CGI in a RESTful manner vs. a GET/POST manner" comment, as well as comments made by others, is it possible that the poll higher up on this page might be yet another example of a poll that is posing several potentially (but not necessarily) orthogonal questions as if they were one question, but doesn't present all of the potential answer permutations? Its almost as if one could pose three polls (assuming that I am reading the poll and people's comments properly, and that entry retrieval is performed by per-entry URI GET):
-
entry submission:
-
POST to single URI vs.
-
direct PUT to a new entry URI
-
entry management:
-
single URI vs.
-
per-entry URI
-
entry management, if through a per-entry URI:
-
via POST only vs.
-
via POST for modification and DELETE for deletion
where "a RESTful manner" describes one permutation of choices but "a GET/POST manner" does not necessarily constitute an opposite choice? Are there certain commonly preferred permutations that we can stick labels on? (e.g. RESTful == (and tell me if I'm wrong here, I'm not a REST expert) entry submission via direct PUT to a new entry URI, entry management via per-entry URI using POST for modification and DELETE for deletion). I ask because while the RESTful permutation is to me a single clear permutation (assuming I'm correctly interpreting REST) there are, however, multiple permutations using "a GET/POST manner" which vary on their use of a single URI vs. per-entry URIs. In short, is "a RESTful manner" tied more closely to single vs. per-entry URIs? Use of PUT, GET, POST, and DELETE? Both equally? Is my whole post nuts?
[AsbjornUlsberg] I haven't had time to read the whole discussion yet, but of what I've read so far, I still haven't seen anyone mentioning mod_rewrite. The "one method, one URL" (Orange) vs "multiple methods, multiple URLs" (Carrot) discussion is kind of useless if we don't discuss what's really possible and what's not. It seems that many belive that the Carrot approach needs several CGI-scripts placed on the different URL's, but that's not the case.
I'm sorry if I seem patronizing or educating -- I'm not -- but I just want to get this said so I can comprehend where everyone is on the technical competence ladder. With mod_rewrite one can have one CGI script placed anywhere on the webserver, and rather have the webserver rewrite (an internal redirect, without notifying the user agent, thus not changing the URL) a request for e.g. "/sports/football/1232.html" to "/script.cgi?category=football&article=1232". This is just an example, but I hope it shows that the Carrot approach isn't much more difficult to program than the Orange.
-
[KenMacLeod] Both of the "multiple methods, multiple URLs" (Carrot) implementations, Joe's above and mine, allow multiple URLs "below" the CGI URL without using mod_rewrite. Using mod_rewrite would definitely open that up to more of the URL space, too.
[AsbjornUlsberg] The multiple method issue is different, as it requires the programming language and framework to support the verbs, which I've understood not all do. I'm very pragmatic about that issue, and don't really care much if we just use GET and POST or if we use all verbs possible. It's more correct to use all verbs, but I understand that this makes it much more difficult to develop in e.g. ColdFusion which doesn't support other verbs than POST and GET.
-
[KenMacLeod] I would definitely like to get a far firmer grasp on what languages, libraries, and frameworks do not support the verbs, or throw exceptions on any status but 200 (Python), or other issues. In this case, though, I do not want to prematurely make architectural decisions based on "maybes". Let's first do a version that follows the web standards as they are intended to be followed and can be easily confirmed works (through working code), and then identify implementation issues, backoff strategies, or whatnot.
[AsbjornUlsberg] +1 I fully agree.
[AsbjornUlsberg] What the RestEchoApi is supposed to base it's interaction on (Orange or Carrot) isn't very important to me, but I feel that the Carrot approach is the best one, especially the part with several URL's. This is because we can standardize URL's to different tasks, e.g. can the URL "http://example.com/echo/retrieve/1232" retrieve the article with the internal id of 1232. If we can standardize URL's, it will be much easier to access information in different Echo-producing systems, as all information is retrieved and accessed the same way on the same URL's. It's just a thought, and I like it, but it may have some backdraughts I don't see at the moment. If so, please enlighten me.
-
[KenMacLeod] I would not want to prematurely standardize URI-space layouts. I'm comfortable now identifying (through introspection) URIs for sending requests to, URIs for basing requests on, and identifying resources through other means (query parameters). It's easier now to specify a general interface pattern (more or less verbs) than it is to specify the URIs used with those verbs.
[AsbjornUlsberg] +1. Yes. But I think the introspection-routine currently outlined is way too complicated. If we can't standardize all URI's, let's at least standardize the one URI on which to get the introspection-file, e.g. "/api.echo".
[Moved from RestEchoApiPutAndDeleteDiscussion]
[MortenFrederiksen,RefactorOk] I've also read Tim Bray's proposal, but I still fail to see why POST is used for all "operations" - PUT and DELETE exist! I realize some might find it a little bit easier to handle, but it makes it impossible to handle security at the lowest possible level, just like the use of SOAP makes anything pass through a firewall...
[KenMacLeod, RefactorOk] The biggest factor I see is that POST (GET) can all be handled by one CGI at one URI, whereas GET/PUT/POST/DELETE have to be supported more at the URI-space level (a top level CGI with some kind of dispatching). I don't see why that's a problem, really. It breaks the RESTfulness of it quite a bit.
[SjoerdVisscher, RefactorOk] PUT and DELETE are not supported together with ASP or PHP (AFAIK), f.e. to run some code when a PUT or DELETE is received.
-
[Arien, RefactorOk] Sjoerd, PUT and DELETE work just fine with PHP (as can be easily verified). ASP's Request.ServerVariables("REQUEST_METHOD") is the method used to make the request. For HTTP, this can be GET, HEAD, POST, and so on. That suggests there would be no problem. I can't confirm that, though.
-
[MikeDavies RefactorOk] Do you have any example code for PHP receiving a PUT request? And will that also require the always_populate_raw_post_data config set to on too? Its the required config change that put me off using PHP.
-
[Arien, RefactorOk] PUT to (e.g.) put.php/foo, where put.php contains <?php echo file_get_contents("php://input"); ?> (this does not rely on always_populate_raw_post_data)
[GeorgBauer, RefactorOk] The RESTish interface should use all HTTP verbs, imo. If you have GET/PUT/DELETE, you can set up limits for those at the webserver level to distinguish between write and read access and stuff like that. It's just usefull. POST is actually a bastard verb, it is a mix of data requests and input method. Especially POST would be a problem if you want to pass in the Necho XML format, as you either would have to encode it as parameter or use some way like XML-RPC does. And PUT/DELETE can be used with most webservers around (ok, you will have to go down on API level to do it, simple CGIs often don't work).
[DannyAyers, RefactorOk] I too would like to seen a good justification of why PUT and DELETE aren't used, it looks cleaner than using POST for everything (I've not used them myself enough to judge). Sjoerd, I don't think ASP needs to support DELETE etc itself : "The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server." HTTP 1.1
[TimBray RefactorOk] I went and carefully read the definitions of the verbs in RFC2616 (I recommend doing this). Calling POST a "bastard" verb is essentially a religious position, it's a well-specified part of the interface. I think all the usages I propose fall within a reasonable reading of the description of what POST is for. And dispatching (based on the request body) within a POST handler attached to a single URI, is going to be a lot easier for most people than setting up handlers to catch DELETE and PUT operations for any random URI in your space. Also, it just feels cleaner to route the editorial transactions through a single gateway attached to the resource which is the publication. I am not saying that an implementation which used PUT and DELETE would be technically wrong in any way, it would just be harder to build and I don't see any advantages to it.
-
[Arien, RefactorOk] A couple of comments on your Web Interace for Web Publishing (Feel free to move if there is a page on this, I couldn't find one.)
-
I agree on using POST for creating an entry (for the reasons you give). The URI for the new entry needs to go in the HTTP headers, though. As does, IMHO, resource-wide modified information. The reply consists of an indication of success or failure, and the URI for the new resource (on success). The resource the method applies to is the weblog.
-
I also agree on using POST (instead of PUT) for modification of an entry but for other reasons: you supply additional information; the server decides what to do with it (e.g. merging HTML content, marking modifications with <ins> and <del> tags). Also, I would imagine that PingBack and comments would alter the state of the resource, so using PUT is not really an option. The resource the method applies to is the entry.
-
Deleting should be done using DELETE. That's what it's for. I can't come up with anything that would justify POST (as for modification). The resource the method applies to is (obviously) the entry.
-
[GeorgBauer, RefactorOk] The problem with POST is that it is a mix of GET and PUT in this case. It modifies stuff, it creates stuff, it deletes stuff and it retrieves stuff. This is bad for security. I like to have the option to set up users with only GET abilities, some with GET/PUT abilities and only a master user to have DELETE abilities. This is quite standard security stuff, you try to differentiate between those operations. If we use GET/PUT/DELETE, we can make use of webserver internal security stuff quite nice (at least for basic stuf - just use the Limit stuff in Apache, for examplef). If we route every modification through POST, we will have to do everything ourselves internally in the POST handler. Actually I think using POST for deletes, creates and modifications isn't very RESTish
-
[Arien, RefactorOk] Georg: something like my outline above? (Using GET/POST/DELETE)
-
[GeorgBauer, RefactorOk] I think POST can be used for creating, as this would need both input and output (the input being the item and the output being the created item, where for example IDs are filled in by the server), but editing should be done by PUT to the items permalink. So actually I would prefer a GET/POST/PUT/DELETE way. This would allow to differentiate between creating and changing, too.
-
[Arien, RefactorOk] I don't see how POST has input and output? Every HTTP request method has "input" (request) and "output" (response). I've updated my proposal above.
-
[MichaelBernstein, RefactorOk] If you're editing via a PUT to the permalink, then which permalink do you use? Entries can be published at multiple URI's, and editing at one URI may cause unanticipated changes at another. By contrast, POST-ing an edit to a central URI using the entry-id is unambiguous, as it implicitly edits all representations of the entry at all URI's.
-
[Arien, RefactorOk] These changes are nothing like unanticipated. From the HTTP 1.1 RFC (section 9.6): A single resource MAY be identified by many different URIs. For example, an article may have a URI for identifying "the current version" which is separate from the URI identifying each particular version. In this case, a PUT request on a general URI may result in several other URIs being defined by the origin server. Reasons for using POST on the entry (instead of some central resource) can also be found in the RFC. (I've given additional arguments in my proposal above.)
-
[TomasJogin] Editing to the permalink does not work. Not everybody uses individual archives, either. Some entries' permalinks consists of the URL to the monthly/weekly archive plus a "<a name='hh:ss'>". Besides that, editing to the permalink assumes that the editing scripts resides on the same virtual host or server as the page itself, which needn't necessarily be the case.
-
[BrentRockwood, RefactorOk] The security issue is significant. As soon as we start putting multiple "functions" in a Post routine, we can no longer rely on simple declarative security provided by the web server and OS.
As an aside, RFC2616 provides a clue of how we might go about PUTting our posts without knowing the permalink beforehand... "If the server desires that the request be applied to a different URI, it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request."
However, this does not seem to be truly in the spirit of the RFC. I believe the important statement is this one... "The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource."
[DannyAyers RefactorOk] Surely the whole point of using DELETE and PUT is that the standard http behaviour is all that is required, i.e. no need for custom handling.
-
[GeorgBauer, RefactorOk] Doesn't PUT just return a status? POST does return content, as does GET. Actually POST and GET are quite similar, only difference being that POST can transfer a payload. But it's some time since I read the HTTP spec, so if PUT can return content in addition to status, just delete my comments.
-
[Arien, RefactorOk] PUT returns a status (as does any method), and AFAIK can return an Entity Body.
[TomasJogin RefactorOk] Using DELETE and PUT may be the "right thing to do" in an ideal world, but the fact of the matter is that a lot -- if not the vast majority -- of webservers do not allow these operations. AFAIK they're turned off in Apache by default (on Red Hat, atleast). I'm in complete agreeance with TimBray's proposal.
-
If this is the case it would swing it for me [DannyAyers]
-
[JustinErenkrantz] The core of Apache httpd supports PUT or DELETE. The default on-disk handlers reject anything other than GET or POST. For instance, a CGI script will receive unknown methods - it is the responsibility of the script to determine what methods it should respond to.
-
[RogerBenningfield] An FYI: Coldfusion (all versions, including MX) does not natively support outgoing PUT and DELETE. I have no idea if it accepts incoming requests of that nature. If anything beyond GET and POST become part of the core API, those of us using CF are pretty much locked out of Echo's REST implementation. Which might be for the best, I suppose, 'cause CFMX's RPC support is where the good stuff lives.
[MarkDrago RefactorOK] I've done some stuff using PUT before, and it is pretty similar to GET/POST. It can return content in addition to a status line. However, it is different because ALL of the PUT requests sent to a server (or optionally a directory) must go through the same cgi script. This is taken from this ApacheWeek Article about PUT w/ apache. So, this script that the PUT requests go through handle all of the actual PUTting of the content. Apache doesn't create these files on its own. This allows for flexibility, but with flexibility comes the need to actually write up this PUT script and change some settings in apache's httpd.conf. It is my understanding that PUT is meant to be used by HTML WYSIWYG editors when they're going to put a file on a server for you (rather than using FTP). I don't think it fits in here.
-
[JoeGregorio] That's not exactly a good characterization of that article, the question the article is trying to answer is if Apache supports PUT like some publishing software expects it to be supported. So, given that question, the article only looks at PUT from that perspective. There is no requirement that all PUT requests to an Apache server go through a single CGI, and all of the security concerns raised in the article really don't apply since the EchoAPI isn't blindly writing all files it receives via PUT into the directory structure, which is the case that the ApacheWeek article is covering. (On a side note I wish that article would be updated, ammended, or deleted since it quite often a source of mis-understanding of PUT.)
-
[MarkDrago RefactorOK] If anyone knows of a newer article describing HTTP PUT with apache, I would be very interested in seeing it. Because, due to my experience with PUT, you have to define a single PUTScript in httpd.conf, and if you PUT something to an apache server at the URI www.example.com/blog/entries/1 or something similar, apache passes all of the information to the PUTScript, not to anything else.
-
[KenMacLeod, RefactorOk] Web Publishing using HTTP PUT [1 and 2] are the second Google hits after the above article, they seem to be straightforward. Yes, at the Apache configuration level, http.conf, within a specifc <Directory> all PUTs go to a specific PUTScript. Or you can choose to identify a CGI script for a directory (in which case all HTTP methods are passed to the CGI program). Or you can choose to mod_rewrite or mod_alias to a CGI script (in which case all HTTP methods are passed to the CGI program). Or you can choose to put the publishing system in cgi-bin or other place where it can run as a cgi (in which case all HTTP methods are passed to the CGI program). Or you can use any number of modules that front Java, Python, Perl or other server-based systems (in which case all HTTP methods are passed to the module).
-
[MarkDrago RefactorOK] This is done because PUT is designed for just sending a file to a web server that the webserver is supposed to store on disk. The URI is used to tell the PUTScript where to store the file. That is most likely NOT happening in a CMS, it is likely going to be parsed through, and the data will most likely be put into a database. I don't think we should force any of these HTTP verbs into a place where they don't belong. We should make this decision based on more than just the verb's name. Just because we're putting something on the server does not mean we should use PUT. We need to look at the verbs technical merits, and based on that, I believe using PUT to be the wrong decision.
-
[KenMacLeod, RefactorOk] I disagree with your assumption of what web servers are to do with representations that are transferred. Replace PUT with GET: This is done because GET is designed for just retrieving a file from a web server that the web server is supposed to read from disk. The URI is used to tell the GETScript where to read the file. That is most likely NOT happening in a CMS, it is likely to use the relative URI as a key to look up the data to return. For reference, HTTP's verbs are also quite analogous to databases: GET (select), PUT (update or insert), POST (insert), and DELETE (delete).
[JoeGregorio] One more reason for avoiding DELETE, it is not supported by XForms.
-
[MarkBaker] Well, I'd say that XForms doesn't need DELETE. For what it does, POST and GET are sufficient. That doesn't mean that I can't DELETE a resource which returns XForms on GET, or accepts XForm data via POST.
[JonathanPorter] I think we should use try to use all the verbs that are apporite (including say OPTIONS) first and perhaps if the need arises then define ways to do all actions with PUT as the non-perferred method.
[MarkBaker] Just wanted to add that if this is to be referred to as a RESTful API, that it would be incorrect to use POST to tunnel the equivalent of DELETE and PUT. Using REST with HTTP requires using HTTP methods, because to not do so reduces visibility. Practically, I also think it's much cleaner to use the various HTTP methods, plus those of any HTTP extension which people may want to use with this API (like WebDAV).
[DonPark] Disregarding reality for sake of adhering to definition of a term or words scribled on papers is silly at best. Server-side PUT and DELETE support is spotty. Live with it. Client-side PUT and DELETE support is even spottier. Have you considered Atom clients in DHTML, Flash, or legacy Java? What about mobile devices and platforms like WAP? What else are you missing or willing to ignore for the sake of using HTTP verbs correctly?
-
[Arien] How is server-side support for PUT and DELETE spotty (which ones and how)? On the client, ActionScript or JavaScript would probably have a hard time doing this sort of thing, although I bet it could be made to work in Mozilla-based browsers (and others using a plug-in). WAP probably won't work because of the four methods here it only requires GET and POST. Java (even "legacy") would definitely work: Java's had socket support from Day 1 IIRC and this ain't rocket science.
-
[TomasJogin] A lot of default installations/configurations of Apache refuse PUT/DELETE requests. Here's what I'm talking about. I did some more investigating and reached the following conclusion: servers with FrontPage Extensions are the ones affected by this; FP automatically adds a .htaccess file which contains:
<Limit put delete> order deny,allow deny from all </Limit>
-
[Arien] Apache does not come with the Frontpage extensions by default (your first two sentences make it appear that way). Although the Frontpage extension is broken in this respect, some searching on Google leads me to believe it can be made to work properly and allow PUT and DELETE requests. Can anyone confirm this?
-
[GeorgeLevy] Some Linux distributions install FrontPage Extensions with Apache (not sure which, but I think Red Hat does). Most web hotels offer FrontPage Extensions.
-
[TomasJogin] I agree with Don here. Denying or ignoring these facts seems to be an ill method of trying to gain widespread support.
-
[KenMacLeod] So far, there are precious few "facts" to go on. As I wrote in Assume the Tools Work, we need specific test cases to go with each assumption about the tools not working as they should otherwise we end up on the slippery slope of requiring producers and consumers to write code to support "problems" we're not even sure exist.
[MartinAtkins] Forgive me if I missed someone else mentioning this in my quick scan of the discussion, but how can PUT be used to post entries when, on most systems, the entry does not have a URI until it is posted? With LiveJournal, for example, the client does not have the information necessary to form a URI for a posted entry until after the entry has been posted. It would seem to me that the obvious behavior is to POST new entries and have the server tell the client the URI of the posted entry.
If it's considered useful, PUT could also be allowed for the purpose of posting to systems which do not include server-assigned data as part of the URL, but that will complicate things client-side: how does the client know which to use?
-
[Arien] There is no prior arrangement: any HTTP method can be applied to any HTTP URI. The client can request (I'll stress that: request) either PUT or POST, the server will let the client know how it feels about the particular request.
[KenMacLeod] I favor the latter: the server tells the client how it can create new entries, whether the client must POST it to a blog-specific URI and the entry-URI is returned in the Location: header, or whether the client can PUT to a URI beneath a particular base-URI, and to what depth.
PUT does not equal Save/Update and DELETE does not equal erase rows from db. When PUT was thought up it wasn't considerd that HTTP would be sitting in front of a DB or CMS. Every tool out there easily supports POST and GET. GET/POST are standard for a reason - they do everything that's needed. In my opinion the XML should have a an arbitrary verb when posting (new, update, delete, mark all, alert, something-else we haven't thought up) and use POST/GET. -- refactored from a comment by RussellBeattie
-
[Arien] PUT and DELETE do not equal, but are analogous to saving or updating and deleting one or more record from a database. Among other documents (this being the first I could find), HTTP Design Issues shows that HTTP was very much intended to sit in front of databases, says the description of the (proposed) SEARCH keyword: Please search the given index document for all items with the given word combination, and transfer the results back as marked up hypertext. This could elaborate to an SQL query. The combination GET/POST does not do everything that is needed on its own: it needs something else (the XML in your case) to fully specify what the request (new, update, delete, mark all, etc). (And if you're referring to the combination of GET/POST and XML being complete, then clearly one of these HTTP methods would be redundant and needs to be eliminated.)
[KenMacLeod] How PUT and DELETE change the "face" of the visible URL space of a server is pretty well defined by the HTTP spec. How actions to a server get implemented is pretty much irrelevant to whether it's an inline XML verb or an HTTP verb. How to implement is also pretty much irrelevant, as somewhere in the code there's a big switch/case statement or its equivalent that says, "for this verb, do this", it doesn't matter whether the verb is in $REQUEST_METHOD or $xml->{soap:Envelope}->{soap:Body}[0]->elementName().
[SamRuby] The "summary above" presumes that a larger URI space is required. KenMacLeod's comment above presents a more pragmatic point of view. Additionally, there is a third alternatve: dispatching on $HTTP_SOAPACTION.
[AsbjornUlsberg] Don't you think it's A Good Thing that Atom can go forth and force the tools to support what they should have been a long time ago? The web has been dictated by the requirements of HTML for a long time now -- it's due time that this changes. The web is undoubtedly most centered around HTML, but the web isn't just that. It's so much more, and exploiting the web to it's full potential is something I think this project should -- and can -- do.
[DonPark] No, I don't think it is A GOOD THING. I don't expect my wife to Save The World while she is out shopping and I don't expect Atom to Force the World to Properly and Fully Implement HTTP in its quest to define its API.
[AsbjornUlsberg] Then lets' agree to disagree. I guess your side will "win" this debate anyhoot.
[TomasJogin] I'm with Don here (again). Atom has challanges to face to establish itself as it is, why invent more obstacles unnecessarily?
[KenMacLeod] I disagree with AsbjornUlsberg that Atom can "force" anything. On the other hand, what I'm still waiting for is anything but hearsay and BabyDuckSyndrome about what tools can or can't do.
[MartinAtkins] I got a bunch of my friends to try to get DELETE to work in some form on their servers. These vary from random accounts on a friends' UNIX box to someone who has his own server and thus has root on it. All of these are using Apache.
The vast majority of the "virtual hosting" people were unable to get their entire URLspace to map to a script on DELETE. The 'Script' directive required to do this looks like this: Script DELETE /path/to/script
This directive can be allowed or disallowed at the server admin's discretion. In all of the virtual hosting scenarios but one it had been disabled. However, most of them were able to get DELETE to a URL "under" the CGI script to work, which then causes the script to be envoked and the bit of URL path after the script name appears in the environment variable PATH_INFO. Two couldn't do this, and I was unable to deduce why with certainty since I don't have access to the configuration, but Forbidden was returned, so I'm assuming these servers had directives forbidding DELETE requests from all clients.
The guy who runs his own server was able to get this to work easily with just a few tweaks to his Apache configuration. However, most people don't have a colocated server running their weblog, so this is hardly ideal.
I played around on my local Apache server with mod_perl. Since mod_perl hooks into Apache's request loop, it was trivial to pick up the DELETE/PUT requests and handle them directly from within the webserver process. However, this is equivalent to installing an Apache server module, and requires access to the main Apache configuration again, which most users do not have.
Using DELETE and POST on URLs "under" the CGI script is possible on many servers, as I mentioned above. However, this means that either a special URL must be used to DELETE so that it can appear under the CGI script, or the entire site must be served from one CGI script, which is quite a limitation. In some scenarios where no configuration is possible at all, this leads to URLs like: http://www.myhost.com/weblog.cgi/path/to/resource -- again, hardly ideal.
I assume that PHP, which in most cases is either itself a CGI program or an Apache module which acts like a CGI program, would work similarly.
POSTing a request with a Content-type of text/atom+xml (or whatever it is) to a "gateway" URL seems to be the most easily-supportable solution. Everyone was able to do that, since all it requires is the ability to run some CGI script somewhere, and if you don't have the ability to do that you're not going to be running any kind of handler, let alone an Atom protocol handler.
I hope my practical testing is persuasive enough. I invite people to try similar things with Microsoft IIS and other servers to see what they can do there. I've not dealt with an IIS server for several years now, so I cannot comment here.
[KenMacLeod] Great work. The only form of DELETE that concerns me is the one that compares directly to "all it requires is the ability to run some CGI script somewhere." In other words, the Apples to Apples comparison: if you can run an Atom publishing system at a "gateway" URL using GET/POST can you not also run the same "gateway" URL as a URL-space with GET/PUT/DELETE/POST underneath it. You indicate you found two that couldn't; since those would be what I consider the most important, could you ask again to see what the reasons might be? One possibility is that the server is running the FrontPage extension and creating a .htaccess file in the CGI directory, denying PUT/DELETE.
-
[MartinAtkins] I got onto the admin of one of the servers by proxy and he says that methods other than GET and POST are deliberately forbidden for some reason he didn't want to tell me. I guess he's using it as a hack method to protect something that I'm not aware of on the server. This means that it's not really a common case situation.
The other server does seem to be running the Frontpage Extensions, but I don't think my friend had the CGI script in the CGI directory, so I'm not sure if that applies.
An interesting alternative which I don't have the means to investigate right now is that of mod_rewrite, which could provide "pretty URLs" for some cases where that is impossible by transforming the URLs before Apache's filename translation phase. A quick glance at a few hosting servers I have access to suggests that mod_rewrite is available on most of them, but that's hardly a useful survey, and I don't know if mod_rewrite can respond to PUT and DELETE requests. Again I encourage others to experiment.
I also managed to grab hold of an IIS user for a moment. I'm sad to report that not only does it not seem to allow PUT or DELETE on ASP scripts, it also doesn't support PATH_INFO in a similar way to Apache. The server I was using didn't have any CGI-based scripting stuff available and I didn't have time to compile a CGI binary, so I can't comment on what these are like.
However, by observation I suspect that PUT and DELETE have the potential to work, since it appears that the "Forbidden" response I'm getting for the ASP script is generated by the ASP handler and not the server itself, which means that IIS is properly delegating the request to the handler and thus other handlers have the potential not to reject it. PATH_INFO is unlikely since the 404 response I got seemed to be generated by the server rather than the ASP handler. (I guess this because the IIS error messages are from disk files while the ASP responses are much simpler and appear to be hardcoded into the ASP handler itself.)
It looks like IIS is going to be a sticking point.
-
Followup: My friend has just informed me that he's found the options which specify which methods are allowable for each ISAPI filter (which is what the ASP handler is). His server was configured to only allow GET and POST yet the ASP handler still seemed to be dispached for PUT. We're now confused, and I submit to someone with more experience with IIS than I.
[AsbjornUlsberg] The problem with ASP doesn't lie within IIS, but in the ASP framework. You can request PATH_INFO and REQUEST_METHOD, but it's difficult to get the content body from the request as ASP only gives access to Request.QueryString (GET requests) and Request.Form (POST requests). In ASP.NET it is pretty straight-forward to do PUT and DELETE requests.
[AsbjornUlsberg] Forward: I've created two examples on how to add PUT and DELETE support in IIS, both in RestAspExample and RestAspNetExample. It isn't very difficult at all. It's quite easy, actually.
[MartinAtkins] Has anyone surveyed popular HTTP proxy servers to see if they restrict request methods? It'd be a pain if they would only allow POST and GET, since in some situations there is no option but to use a specific proxy server.
[AsbjornUlsberg] I've made a suggestion that might solve this in the bottom of CarrotVsOrange. Please check it out.
[HansGerwitz RefactorOk] As a server implementor, I like Carrots, as I only have to "broadcast" a single endpoint URI for each space. As a client implementor, though, I am offended by the redundancy of tracking a per-entry URI for identification, and a per-space URL for operations on that entry. I cannot imagine many scenarios where I needn't keep a URI for each entry, so why not use that URI as the API URL?
CategoryArchitecture, CategoryModel, CategoryApi, CategoryRest