UserPreferences

CarrotVsOrangeDiscuss


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.

[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?

[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).

[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):

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.

[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.

[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.


[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.

[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." [WWW]HTTP 1.1

[TimBray RefactorOk] I went and carefully read the definitions of the verbs in [WWW]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.

[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.

[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.

[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 [WWW]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] One more reason for avoiding DELETE, it is not supported by [WWW]XForms.

[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?

[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?

[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

[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] 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