Hacker News new | past | comments | ask | show | jobs | submit login
Let's remove verbs from HTTP 2.0 (onebigfluke.com)
113 points by bslatkin on Aug 9, 2013 | hide | past | favorite | 136 comments



Arguing to replace a well-defined single idiom (verbs) with some arbitrary combination of URI, custom headers, request body contents is exactly the opposite of what you want. Using defined verbs instead of having each site do their own slightly different thing makes APIs easier to discover / consume.

Also, I feel like "Execution in the Kingdom of Nouns" is semi-relevant here: http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom...


> Arguing to replace a well-defined single idiom (verbs) with some arbitrary combination of URI, custom headers, request body contents is exactly the opposite of what you want.

It may not be what you want, but it is what you'll get. It's what you'll get now, and in the future. There isn't much in the way of discoverable APIs that adhere to the data model suggestion in the HTTP spec, and that's becoming more true as time goes on. As HTTP APIs become more popular they have become less normalized. It's natural: if you want to expose something, you want to expose it as it is. Not many things adhere to the verb structure of HTTP, I'm not sure anything does unless it was designed to be HTTP from the ground up – which isn't how you should design an API, you should design it to do something useful from the ground up.


> There isn't much in the way of discoverable APIs that adhere to the data model suggestion in the HTTP spec

I don't even understand why this needs to be pointed out. If the precise usage of all web APIs could be inferred from the verb alone, presumably all web APIs are exactly the same. That's nonsensical. I challenge anybody to honestly claim they have consumed a 3rd party web API of material complexity without once referring to the documentation and solely relying on guessing HTTP verbs.

Once you're already reading the API documentation, I don't understand why you'd prefer "http.request('PUT', '/resource')" over "http.post('/resource/put'). Even better, you can choose a URI that makes the most sense to your domain model, e.g. '/resource/upload'. I don't understand why you'd want to have less expressive URIs AND more work. In even this simple example, the verb is unlikely to be adequate in any case - if you need to supply options or metadata the verb is even less significant as to the true meaning of the operation.

The fact is you can always embed the verb of your choice into the URI - thereby making a GET/POST/HEAD world no more or less expressive than a Verbtopia world. All that extra verbs do is cause consumers of the API to have to remember two pieces of information (VERB + URI) rather than one (URI). At least URIs can be constructed to make as much semantic sense as possible within a given domain model - VERBs, on the other hand, end up as square pegs in round holes, making them far less memorable.


Ideally, a REST API would only require consulting the documentation on media types and the location of the root endpoint, but the kind of media-type heavy, hyperlink driven driven specification that would support that is rare.

Though specifications aimed at improving at least the hypermedia part of that are starting to gain traction.


I still don't see the value. To me it's like proposing that in SQL we replace 'EXEC' with 'HEAD', 'PUT', 'DELETE'...

At the end of the day I still need to understand the contract of the stored procedure to have any hope of consuming a database API of meaningful complexity.


> I still don't see the value.

The value is loose coupling and composability; each media-type is its own contract, and hypermedia provides a common mechanism for discovering the location of endpoints.

This allows different APIs (and their clients) to share common components rather than every large API being a special snowflake.

> To me it's like proposing that in SQL we replace 'EXEC' with 'HEAD', 'PUT', 'DELETE'...

A better SQL equivalent is proposing that you expose to each consumer an appropriate set of relations (likely views) as the application's interface to the database rather than stored procs (the data description of the view is the analog of the media type of the REST resource.)


I think the argument was to remove just the unused verbs. I think GET, POST, and HEAD are the ones that make up 99.9% of all use on the web and those are the ones the author thinks should be the only verbs in HTTP.


> I think the argument was to remove just the unused verbs.

What unused verbs?

You know the outcry that got Google to restore CalDAV access to Google Calendar data?

CalDAV adds its own method on top of the whole stack added in WebDAV, as well as borrowing one from the Versioning Extensions to WebDAV (I don't think it actually relies on the whole Versioning Extensions.)

All the HTTP/1.1 verbs (well, except maybe TRACE) -- plus PATCH, plus those in WebDAV, plus many of the extensions to WebDAV (including CalDAV), are all actively used in the wild, on major systems.

I'm no fan of the WebDAV ones, but since its an extension on top of HTTP/1.1, I don't see how HTTP/2.0 could kill them except by forbidding extensions. Which, given the success of Google's attempt to drop CalDAV, I don't see being particularly successful if HTTP/2.0 wants to get widespread adoption (if it doesn't support HTTP/1.1 verbs including extensions, then existing HTTP/1.1 -- and WebDAV extended -- services aren't going to be easy to move over.)


GET, POST, and HEAD are the only ones used because since time immemorial, they've been the only ones implemented by the browsers (NN, IE, FF, etc.).

I posit that if Netscape had implemented PUT, we'd all be talking about the four main verbs, instead of the three main verbs.


99.9% What? Has nobody on HK ever used REST either as a consumer or producer?

http://en.wikipedia.org/wiki/Representational_state_transfer...


sure we have. have you read through the developer docs for most API's? here's twitters:

https://dev.twitter.com/docs/api/1.1

its all GET and POST. this is typical.


I just wrote a REST API for my company and used PUT and DELETE (Tomcat doesn't support PATCH yet).

Plenty of DELETE in Stripe's API: https://stripe.com/docs/api#delete_recipient

Github uses HEAD, PATCH, PUT, and DELETE: http://developer.github.com/v3/#http-verbs

Twilio supports PUT and DELETE: http://www.twilio.com/docs/api/rest/request

There are all darlings of the HK community with highly praised, widely used REST APIs. Have you read through the developer docs for most APIs?

(edit: typo)


To be fair to the other poster, I wouldn't be surprised if 99.9% of requests were GET/POST/HEAD.


And 99.9% of requests are GET rather than POST, so shall we get rid of POST then?


GET and POST already have widely observed distinctions in how they should be handled. For example, try hitting refresh on a page that was arrived at via a POST request. That behaviour is pretty much common to all browsers.


His point was that at minimum you still need a GET and POST for read and write. So comparing the numbers against bike-shed implementations is moot. Of course the number of reads will be significantly higher.


You could write and read using just POST. SOAP is the living example of that. So I think his point is inconsistent.


Okay, here's Google Drive's

https://developers.google.com/drive/v2/reference/

it uses GET, POST, PATCH, PUT, and DELETE

Here's (part of) the Amazon S3 API:

http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketOps... http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectOps...

HEAD, GET, DELETE, PUT, POST


And that makes the API better because...?


I'm responding here to the claim that the verbs other than GET, HEAD, and POST are generally unused in APIs.

The discussion of the merits of the verbs aside from their frequency of use in APIs is on other subthreads.


That's Twitters'.

Twitter has no concept of edit for a tweet. Is it surprising then that they don't need to use PUT or PATCH?


Problem is, in a lot of circumstances, you still have to rely on GET and POST with a header like X-REQUEST-METHOD set to tell the server what you really meant.


Usually, this is not the server not supporting it, its a workaround that the server provides so that you can consume the API without AJAX from HTML forms, which are restricted to GET and POST.

EDIT: Although in some cases there is an issue that people choose not to configure it on the web server, and instead use headers or other mechanisms to tunnel the "real" method to the application. But most servers do support it, this seems to be a mechanism for routing around administrative issues in organizations.


“But most servers do support it, this seems to be a mechanism for routing around administrative issues in organizations.”

Spot on.


"Execution in the Kingdom of Nouns" is excellent. Anyone who hasn't read it should do so immediately.

I want some expansion of verbs, counterbalanced with the elimination of some of the less useful verbs.

The focus should be towards forcing webbrowsers away from GET and POST.

OPTIONS should be made mandatory.


Hadn't read it. Did so immediately. Very good read! God I love it when people hate on java. (I know I shouldn't, but I do.)


He's not only bashing java but writes a lot of java. Are you as comfortable with that?


Sure why not. Makes his opinion even more valid. There is a LOT of truth in that essay.


I write tons of Java in my day job, and at this point it only hurts when I laugh.


Thank you soo much for "Execution in the Kingdom of Nouns". It 's been a while since I cried laughing. As someone who's been programming in java since 97 (..God I'm old) I certainly saw myself wandering around the Kingdom of Nouns


"Practically speaking there are only two HTTP verbs: read and write, GET and POST."

And thus spoke someone who has never built a REST API, never used curl -I, and probably hasn't used anything other than a web browser to access HTTP content.

Sure, for the most part, we're all kinda new to REST, and we're slowly learning to construct good REST architecture. Sure, there's some redundant weird shit like SPACEJUMP. But we should aim to improve education and encouragement of the use of verbs such as PUT and DELETE, rather than abandon best practice because "no-one's going to use it" or YAGNI, when we can clearly see in talk after expert talk that these are the practices that are being recommended and already put to good use.

Not to mention the plethora of proxies, web servers, and tools that already support these accepted, recognised, standards-defined techniques.


"And thus spoke someone who has never built a REST API"

Here are Brett's projects: http://www.onebigfluke.com/

Maybe you've heard of some of them? PubSubHubbub, Google App Engine, Camlistore, Google Consumer Surveys.


I'm sorry, I must have missed the <hyperbole> tags.

Yes, the comment is embellished, but the only place where GET and POST are the only verbs is in a basic web browser. Step outside that world, and the other verbs are in use every day…and intermediary devices - with no knowledge of the business logic of the target server - accommodate those verbs, with proper behavior for the most part. Moving those to the URL means that intermediaries cannot disambiguate the intent.


It wasn't really hyperbole, it was just wrong.


Um, I suggest you look up the definition of the word "Hyperbole". I understand that as a Googler, you wish to defend a fellow Googler, but please differentiate between the arguments of "I disagree with the premise of your argument" and "You're wrong". As a Googler, I'd hope you are reasonably technically literate, and therefore could come up with a rather more refined response than "You're just wrong".


Hyperbole means exaggerating something, usually for emphasis or humor. Even taking your comment as hyperbole, the intended, non-exaggerated meaning still appears to be "this person has insufficient experience to speak on this subject." But the person in question is actually very experienced in this area. Given that, I don't think we can blame James if he didn't understand — it's hard to see what the actual meaning behind the statement could have been.


Yeah, I know what hyperbole means. The problem is your comment was not even in the correct direction. Hyperbole is overstating a truth, not strongly stating something false.

And, this guy is a Googler? Who knew? You know your argument is weak when your best responses are "look it up in a dictionary," and "you work for the same company hur hur."


My point about hyperbole was that it's "an extravagant statement or figure of speech not intended to be taken literally". To be fair, I hadn't come across Brett's work before…but anyone writing with degree of detail about HTTP headers, referencing SPACEJUMP and PubSubHubbub has probably used curl -I and may well have worked with a REST API. My point is that the argument - we only use GET and POST - only holds water if we're talking about browsers. although I do see how people could interpret the comment differently, and we all know duty calls: http://xkcd.com/386


"The guy build appengine" isn't a convincing argument either. This is a personal blog, not a peer reviewed journal. Sometimes even distinguished people throw out 270 words without thinking too much about it.


In my mind, two HTTP methods exist: encode things in the URI or encode things in the body of a request.

Go read the RFC definition of PUT and report back. I can never understand it. If anything, PUT needs to be retired in favor of something unambiguously specific like CREATE. In fact, why not go all the way and make all HTTP methods just CREATE, READ, UPDATE, DELETE? That's the only change I (as a nobody) could get behind.

We're not kinda new to REST. REST has formally been around since 2000 and people have been using it heavily since a little before 2008.

Browsers seem to not want to support anything other than GET/POST in forms, so we hack it with running other methods over GET with _method params. Why bother? Just use GET/POST and let the endpoint denote what your intentions are, then have the server side code validate, perform the operations, return results, etc.

(Still rambling: I think one reason REST methods (not URL structure) bother me is it allows lazy (or inexperienced, or incapable) server side programmers to just allow what the client wants. Oh, the client wants to DELETE? Sure. They know what they're doing. No ACL/ownership checks needed). Removing the ability of the client to forcefully say "CREATE/DELETE" may (may) remind the programmer (who is in an outsourced operation in CantProgramistan) they are responsible for the data, not the client asking (asking, not demanding) for operations on the data.)


> make all HTTP methods just CREATE, READ, UPDATE, DELETE

No, because resources are not necessarily mapped to database records, nor even behaving like so.

Being able to implement various behaviors in terms of the generic but very well defined HTTP verbs is important, notably PUT being idempotent is extremely useful.


not necessarily mapped to database records

Examples?

nor even behaving like so.

Examples?


Your API could be mapped to a filesystem. (Although you might consider consider a filesystem a database.) If this were the case, it would make sense to use PUT for commands like chown and chmod, which are idempotent. Calling "PUT" "CREATE" here would (IMO) be confusing. I'm not creating something. I'm performing an action, putting things in their proper place, if you will. Another example could be home automation. You might design a REST API where you can PUT cameras to turn them on.

The way I see it, the great thing about HTTP verbs is that they are mostly (not all) unbiased about what they map to, and allow us to be more descriptive. If I'm inspecting the requests my browser is making, I'd much rather see "DELETE /path/to/resource" than see "POST /path/to/resource" and only discover that that call deleted my resource because the body of the request contained '{ "action" : "delete" }'.


Doing a "chown" or "chmod" would be an UPDATE operation, not CREATE. The permissions and owner values already exist by value of the record existing, so of course trying to call CREATE on them seems silly. Same with turning cameras on/off; that's UPDATE on the state on the camera. CREATE would be to add a new camera to the system.


> Doing a "chown" or "chmod" would be an UPDATE operation, not CREATE.

Right, which is why calling PUT to do them "CREATE" would be confusing. But PUT is still the right verb (well, for things like chmod 777; for chmod +X, PATCH would be better.)

PUT isn't "create" its "assign".


> Go read the RFC definition of PUT and report back. I can never understand it. If anything, PUT needs to be retired in favor of something unambiguously specific like CREATE.

PUT is unambiguously defined as "take the request-body, and make it the resource at the given URI". If it was named by the creators of SQL, it would be CREATE OR REPLACE RESOURCE <uri> WITH <request-body>.

(OR, if it was BASIC, it would be "LET <uri> = <request-body>".)


I my mind, there are only two kids of HTTP transactions: Those that can be repeated over and over safely, and those that can't.


Exactly. REST screws with our internal matrix of "things allowed on methods." Instead of idempotent GET and mutating POST, what does PUT do? Can DELETE be run twice? I'm sure the RFC says, but it just adds additional complexity on our heads (which we may want to override on a per-case basis anyway).


GET is idempotent and safe.

POST and PATCH are neither safe nor idempotent.

PUT and DELETE are idempotent but not safe.

Its not really that complex.

GET alone is safe -- it doesn't have side effects. The results of POST and PATCH depend on the current state of the resource they effect, so they aren't idempotent. The results of DELETE and PUT don't depend on the current state of the resource they target, so they are idempotent.

> I'm sure the RFC says, but it just adds additional complexity on our heads (which we may want to override on a per-case basis anyway).

If you don't want to use the semantics defined in the RFC for a particular method, use the method with the right semantics.


Spoken like someone who has never looked at any of the other stuff that Brett Slatkin has worked on. PubSubHubbub to name just one.


These best part of the post is Tim Bray's response, where he says he would keep PUT and DELETE because they're idempotent, but declined to defend the rest.


Huh? DELETE is rarely necessary nor semantic in HTTP. Personally, it's usually more often...

  -d"status=0" /document/<id>/
Even on an FS, you are more likely semantically switching off its visibility or its fd and not necessarily destroying the underlying bits. The resources are then collected and destroyed at a later and in batch, kept forever in a deactivated state, or written over.

And PUT is often a disaster, because few resources show all its properties in public, and if you're not replacing the resource, is PUT the right semantic?


> Even on an FS, you are more likely semantically switching off its visibility or its fd and not necessarily destroying the underlying bits. The resources are then collected and destroyed at a later and in batch, kept forever in a deactivated state, or written over.

So what? All of that is consistent with the semantics of HTTP's DELETE method. From RFC 2616:

  9.7 DELETE

    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. The client cannot be guaranteed 
    that the operation has been carried out, even if the 
    status code returned from the origin server indicates 
    that the action has been completed successfully. 
    However, the server SHOULD NOT indicate success unless, 
    at the time the response is given, it intends to delete 
    the resource or move it to an inaccessible location.

    A successful response SHOULD be 200 (OK) if the response 
    includes an entity describing the status, 202 (Accepted) 
    if the action has not yet been enacted, or 204 (No    
    Content) if the action has been enacted but the response 
    does not include an entity.
 
If you are going to say that the semantics of an HTTP method are not right for a particular scenario, there should be something in your description of the scenario that is inconsistent with the semantics of the HTTP method in question.


Sticking to the article -- not that I'm strictly suggesting DELETE is useless -- the extra verbs confuse the process. POST already covers DELETE, including the response codes. PUT is often more confused. And then PATCH. And then the rabbit hole. That is, DELETE can be semantically correct, but POST would be more so.

Notice that, the quoted RFC does not state the resource is not inaccessible after the operation, only that it is intended to be.

And perhaps I'm talking out of my ass, but the number of DELETE operations is likely vanishingly small for HTTP resources.


POST is not idempotent, DELETE is idempotent. That's a pretty significant difference. Yes, obviously, you can use POST in place of DELETE (heck, plenty of APIs have used GET in place of everything), but its not a good idea, and losing DELETE in favor of POST loses clarity.

> That is, DELETE can be semantically correct, but POST would be more so.

DELETE is both more specific about intent and more specific about the idempotence of the operation, so, no, POST would be less semantically correct for any operation where DELETE is semantically correct.

> Notice that, the quoted RFC does not state the resource is not inaccessible after the operation, only that it is intended to be.

Actually, it says that success (2xx) series codes should not be returned unless the server intends to complete the operation, and further specifies that that 200/204 codes indicate that it has enacted the operation (differing in whether a response body is included) and 202 indicates that it has accepted the request but not enacted the operation yet.


Idempotent methods are important; I'll give you that. However, the struggle between ACID and CAP theorems would suggest these are just words we will try to live by. I rather dislike having to imagine what it means for my DELETE operation to be bouncing around the network for a minute.

  > unless the server intends to complete the operation
A gerund; it intends to, without any guarantee of recency, to perform the operation. The very same problem that required the operation to be idempotent; it can't be guaranteed the operation is already done, only that it intends to complete in time. A 200 will only describe the status and does not require the description to be "deleted."


I can't agree with the assertion that the methods defined in HTTP since 1.0 are bike-shedding. I'll agree that lots of the the HTTP methods defined in standards other than HTTP are unnecessary cruft (particularly in light of the REST model) -- WebDAV and friends particularly -- but I don't see why you'd want to eliminate any of the HTTP/1.1 verbs (or PATCH) in HTTP/2.0, except maybe replacing HEAD with a no-content media-type in the Accept header for a GET request, and maybe dropping CONNECT and TRACE (though I suspect that there may be cases where they are used and critical, I've just never seen it.)


CONNECT is used to get a raw socket connection through a HTTP proxy. There'd be no way to get SSL/TLS to work with a proxy without it (save using SOCKS instead of HTTP to talk to the proxy).


Good point on CONNECT; not something I work with directly, but I'm still embarrassed that I spaced that out.


There are two valid reasons I can think of why the verbs need to be specified somewhere for universal agreement:

- So that proxies can potentially retry idempotent requests if the upstream fails. Retrying a partially sent GET should be ok, while retrying a partially sent POST is a terrible idea. It's nice in theory, but in practice only reverse proxies at the application endpoint really have the information necessary to make this decision, since many sites have non-idempotent GETs.

- Because it affects whether or not there's a request or response body. GETs have no request body but should have a response body. POST/PUT/etc. should have both a request and response body. HEADs have neither a request nor response body. At the moment the only way for an intermediary to know whether a request is finished is because it understands these methods, and this is also true of any extension methods (which is why proxies should generally fail on unknown methods).

Mostly it comes down to an issue of routing. And in the end, the ability to have working proxies was an important factor in the popularity of the web imo.

But really the first issue is largely moot already and the latter could be fixed in the protocol so that presence or absence of a body could be signalled in the protocol itself (probably is in http2.0 actually).

All of that aside, though, http2.0 may never fully replace http1.1. I think there may even be a large portion of the web development community that is hoping it won't. In which case, interop will keep those verbs in place forever.


> At the moment the only way for an intermediary to know whether a request is finished is because it understands these methods, and this is also true of any extension methods

I read the HTTP 1.1 RFC differently. Requests must indicate a body with a Content-Length or Transfer-Encoding header. Responses always have a body (sometimes of length 0), unless it is a response to a HEAD request or has one of a very small number of response codes. http://tools.ietf.org/html/rfc2616#section-4.3


As I understand it... Only convention is the reason GET does not usually a body. The spec doesn't prevent it.


When you think about it, any application can represent every piece of information coming from the outside world in unified data structure. That is, there is no real difference between headers, parameters, and body content (except, of course, in those cases where it is self-referential - for example, when a header tells you how to interpret the rest of the message. But even then one can write a totally generic function that does that first pass for you). When modeled this way, there's really not even a useful difference between GET and POST. These days all GETs cause writes to occur anyway, even if they are just analytics.

Indeed, I'm constantly surprised that there aren't more "grand unified APIs" for dealing with HTTP. If there were, then we'd have better consensus on just how useless a lot of the HTTP spec has become, verbs included. It reminds me of the Java Servlet API - much of it became worthless with the advent of Struts and SpringMVC, as the front controller pattern better fit the mental model of people writing applications.

That said, GET, POST and HEAD are probably worth keeping around, because at least the first two imply something about the kind of idempotency your callers should expect, which is useful.


Is HEAD really used a lot? I don't know that I've ever used it except to try it once. Is it used in API call? If so, why? Thanks for any help on this.


The Web Linking RFC [1] uses it to do discovery. The HEAD is mainly used to get ahold of the "Link" response header.

    > HEAD / HTTP/1.1
    < 204 no content
    < Link: <foobar.com/>; rel="self service"; title="Foobar!",
            <foobar.com/users>; rel="collection"; id="users"

    > HEAD /users HTTP/1.1
    < 204 no content
    < Link: <foobar.com/>; rel="up service"; title="Foobar!",
            <foobar.com/users>; rel="self collection"; id="users"
            <foobar.com/users/bob>; rel="item"; id="bob"

    > GET /bob HTTP/1.1
    ...
GET can't support that process, so that's just one reason why I'm against ditching the extra verbs.

1 http://tools.ietf.org/html/rfc5988


Why can't GET support that process? You'd have the extra bytes of the content, but there's nothing stopping the server sending the Link header in response to a GET request.


It's already a pretty chatty protocol; if you can support the HEAD request, why not do so and save the bandwidth?


Yes, it's used a lot. If you look through web server logs, you'll see tons of cases where a search engine spider performs a HEAD, and then based on the headers, it decides whether the content has changed since last fetched. If so, it issues a GET.


Say you have a list of downloads, and you want to know how big they are. With HEAD and Content-Length, you can know, in a standard fashion, assuming the server tells you. Isn't this basic enough, that you'd want to put it in HTTP? What else would you do? Application-specific file-size queries? Doing a GET and then just closing the connection after headers? That's not pretty!


That makes sense. I was not challenging the inclusion of HEAD in the http verbs, just stating my own ignorance and hoping for illumination, which you and others and have now provided. I appreciate it.


personally I use HEAD quite often in the form of `curl -I` if I want to check the size or mime type of a particular resource.


While we're at it, let's remove HTTP headers and request bodies, and just stuff everything into the URL. I've written tons of shitty webapps that do exactly that, so it logically follows that we should force everyone to do it.


I was thinking something more along the lines of proprietary extensions to HTML5. Isn't that what everyone's doing now?


The article doesn't present a compelling case for it, though. It points out some quirky aspects of HTTP's history, and concludes "therefore let's remove the verbs" while ignoring the fact that lots of people are literally using the verbs, successfully, right now, and the fact that there's this whole history of SOAP and REST and why having arbitrarily lots of verbs might be a bad thing. It should at least dimly acknowledge those things, before baldly asserting "let's remove the verbs and let people define their own stuff." That's what SOAP did and it failed.


Don't we stick everything into the body of a JSON object in a GET request these days?


Sure, plenty of people do that, but it's a horrible way to design a web API in my view, and it's definitely not a pattern anybody else should be encouraged to follow.


Yeah, it's SOAP all over again.


But I use spacejump to heat my room! It's part of my workflow.

http://xkcd.com/1172/


If anything, I'd rather have a HTML spec that allows forms to do the other resource oriented verbs.


Yes! Why is support for PUT and DELETE not specified in HTML specs? Also, why hasn't a browser implementation gone ahead and added support for both of those verbs as an extension beyond the spec?


> Yes! Why is support for PUT and DELETE not specified in HTML specs?

IIRC, it was in an earlier draft of the WHATWG HTML spec, was implemented in a beta version of Firefox, issues were raised with the semantics of the Firefox implementation that ended up becoming issues with the clarity of what browsers were supposed to do with PUT/DELETE forms in the draft HTML spec, and the result was taking PUT/DELETE support out of the spec because of the lack of agreement on what should be specified regarding the use of those methods with forms.

ISTR that this issue has been reopened as a bug with the spec since that time, though I don't know if it is currently open or not.


My understanding is that "PUT" means "make it so that the contents of this request body live at this URL". Meanwhile classic HTML forms only send lists of name/value pairs. So it would have been saying "make it so that this list of name/value pairs lives at this URL" which isn't very useful and would likely have led to widespread creative abuse and corruption of the meaning of "PUT".

Likewise, it doesn't make much sense to send a request body with a DELETE, regardless of what it contains. Not forbidden, but not really useful either.


The server can do whatever processing it likes to a PUT's request body. If you upload a PNG it can convert it to a JPEG or an SVG or OCR it or invert the colors, etc. It's perfectly valid to turn application/x-www-form-urlencoded into something else.


Converting "image/png" to "image/jpeg" is easy given a knowledge of those formats, but how do you convert "application/x-www-form-urlencoded" to "image/jpeg" or "text/html" or anything else? The only thing you can do is invent your own arbitrary convention, which begins to stray pretty far from the design and intent of PUT.


That would depend on what kind of service you're implementing.

"HTTP/1.1 does not define how a PUT method affects the state of an origin server."

I don't think it was ever the design or intent of PUT to store the exact representation that you gave it, and I would be surprised to see evidence otherwise.

Conceptually it's no different from POSTing (or PUTting) application/json to produce a resource that will be represented as text/html. How do you convert JSON to HTML? Depends on the service.


The only real difference between PUT and POST is that PUT creates a resource at a defined location. There's no difference with regard to the mapping-from-request-representation-to-preferred-server-representation between PUT and the common use case of POST to create a new member of a collection where the collection URI is the target of the POST, the only difference is that with put, the target URI is the location that the resulting resource will be placed rather than the location it will be subordinate to.

Since this problem isn't a barrier to using POST to create resources, it shouldn't be for PUT, either.


HTTP and HTML are two different things. If you don't like HTML you are welcome to use a different markup format.

This post is all about how the author thinks the other verbs are useless, and they are pretty much useless in the browser. However, HTTP is not just for browsers...


But it seems to me that one of HTTP's prime benefits is its ubiquity. And it's ubiquity is due entirely to its use by browsers.


TIL: I shit you not – SPACEJUMP was once an HTTP verb


...and <BLINK> was a HTML element. Let's not throw out the baby with the bathwater.


It never was. <BLINK> has never, ever, ever been part of the HTML spec or even the HTML drafts. At best, it was an easter egg.


And SPACEJUMP has never been part of the HTTP spec.

Nor (unlike <BLINK> in HTML) has it been part of HTTP implementations, AFAICT, at least, as an HTTP verb.

The "SPACEJUMP" and "TEXTSEARCH" methods appear to be patterns for use of the GET verb.


I'm forced to agree. It's pretty much a consensus that the best specs are the smallest ones. You want just the right amount of abstraction to be useful, not try to cover all possible use cases. Inevitably, people will build another layer of abstraction on top.


Adding un-necessary VERBS adds complexity that imposes additional knowledge and burden that increases the surface area that web servers, server software, intermediaries, HTTP Clients, client libraries, browsers, etc need to know in order to support it.

What are the call-semantics of the new VERB? Will it be widely used correctly and can we even rely on the spec'ed definition? There's no value adding new VERBs that have the same semantics as POST but just has additional metadata to indicate what the action is. Lessons from WS-* should be not to try add specifications and written unified/concepts for everything but to keep a simple and minimal but flexible specification, that most APIs can operate within.


Adding unnecessary verbs to the standard does create problems, but having a few standard verbs and controlled customization is fantastic. The trouble with custom verbs, like you touched on, is the inability to advertise their contract. I would argue that the OPTIONS verb does not give back enough information to make it useful. Either the OPTIONS verb needs to return more information, or an additional verb should be standardized to allow for discovery and use. The level of specification is a good debate to have, because WS-* was to much specification and REST is almost too little.


I think until we have a way of doing automated service discovery for REST (and OPTIONS is a very lame excuse, knowing what verbs I can use gives me nothing), having 10 bajillion verbs for slightly different semantics doesn't matter. Having a small and standardized set of verbs helps developers, and that's all that matters.

And even if we can do automated discovery, what does that really give us? What software is there that automatically crawls unknown APIs, discovers functionality, and then does something useful with it? The semantics of the commands matter, and it's hard to infer that unless you're a human. No amount of HTTP verbs will fix that. For now, good documentation is fine.


That's why you should be careful about adding concepts because you can't remove them without breakage.


The key difference between POST and PUT & DELETE is idempotency. To quote wikipedia "This is a very useful property in many situations, as it means that an operation can be repeated or retried as often as necessary without causing unintended effects. With non-idempotent operations, the algorithm may have to keep track of whether the operation was already performed or not."

Read Fielding's dissertation please, or any distributed systems text on the basics of RPC. HTTP is for more than just CRUD websites.


Good read, plus I'd never read the email that introduced the bike-shedding metaphor: http://white.bikeshed.com


I also strongly disagree. The real problem is that browsers can't use them as good as they should. If you take for example a RESTful API, the verbs make totally sense and especially one of the mentioned verbs. PATCH is a great verbs if you use it like it was specified. I personally like the idea of giving more freedom to chose the verbs. Imagine you could use for a Twitter API something like: FOLLOW /users/123


> The real problem is that browsers can't use them as good as they should

That's the obvious inevitability of having too many superfluous options. And one of the main thrusts of the article.


Yes, but people disagree on the "superfluous" part.


Yes, it would be horrible if you instead had to do: POST /user/123/follow


PUT /myuser/following/theiruser


PUT /user/123 { id: 123, following: { foo, bar, baz } }


  PUT /user/123/following

    /user/foo
    /user/bar
    http://www.other-site-using-standard-formats.com/user/baz
Sigh, if only.


Yeah, if that's where your URL ended. But what if your URLs kept going? Say you had

    /user/123/followers
or

    /user/123/followers/followers
or

    /user/123/followers/followers/following
? When your URLs have a non-obvious terminus (as is typical of proper REST APIs) it becomes clear that the verb does not belong in the URL path.


So you're saying that we should have a verb instead?

FOLLOWERS_FOLLOWERS_FOLLOWING /user/123


No, the verb is FOLLOW, as in the example you were responding to:

    FOLLOW /user/123/followers/followers/following


The HTTP specification in no way restricts the verbs that you can use to those that are in common use. But at some point somebody, somewhere, decided that the only ones allowed were the ones that the specification explicitly mentioned. And so people just shoehorn their applications into frameworks built around what the HTTP specification defines, rather than allows.

Ain't nobody got time for defining semantics.


Javascript can use them just fine. Browsers without JS can't do a lot of useful things, that's why JS exists.


Thinking about it further, it's an interesting question. A typical HTTP system has 3 roles: the client, the intermediaries (proxy/proxies/CDNs/caches), and the application (which combines the server, and any edge devices with knowledge and behaviour that is specific to the application).

Currently, the business rules are governed by a complex interrelationship between the request method, request headers, and response headers (including response status).

Although request and response bodies may be present, I've not come across any system where the contents of the body affect the business logic of intermediaries.

Yes, this could be simplified. But chucking out the request methods is both a low-hanging fruit, but also a short-term saving. Much of the complexity is in the request or response headers (such as Vary), whilst the request method provides a consistent and simple community standard.

One of the common limitations I come across is caching of content that varies according to the individual user (or perhaps the role(s) that user has access to within the site).

Most web systems send a plethora of cookies - for google analytics, web tracking, advertising, a dozen other things, and eventually for the session. But the proxy-controls that can be sent are limited to "Vary: cookie". This reduces the cache-potential massively. If I were to request one improvement in the HTTP 2 protocol, it would be the ability to vary according to a particular named cookie, rather than the entire cookie header.

Oh, and yes, I am aware of the ability to parse the cookie in a proxy, extract the proper key-val params, and vary according to that…but it adds unnecessary complexity to the application, and you can't currently expect uncontrolled downstream proxies to accommodate this practice.


Removing DELETE and PUT would be a terrible idea, every REST API would break.


I thought someone would say this and I'm afraid it's bullshit. You can just put the REST operations in the URL. This also has the advantage that you aren't artificially restricting yourself to CRUD operations. Some operations do not map to those, e.g. logging out (DELETE user? ... No... DELETE session? I guess?).

I explained in more detail here: http://stackoverflow.com/questions/2191049/what-is-the-advan...


> I thought someone would say this and I'm afraid it's bullshit. You can just put the REST operations in the URL.

That breaks the basic, clean, clear model of HTTP:

  URI: specifies the resource against which an action 
    is to be performed
  Method: specifies the action to perform against the 
    resource
In favor of a muddy model of:

  URI: specifies a combination of the resource against
    which an action is to be performed, and some 
    information about the action that is to be performed 
    against the resource
  Method: specifies incomplete information about the 
    action to be performed.
Why on Earth would you want to do that?

> This also has the advantage that you aren't artificially restricting yourself to CRUD operations.

I'm try to think of an operation in a system that can't be fairly clearly represented with the semantics of HTTP/1.1 verbs + PATCH, and failing.

> Some operations do not map to those, e.g. logging out (DELETE user? ... No... DELETE session? I guess?).

DELETE session is pretty natural. PATCH session to change the status to closed or, if the session status is its own resource, PUT closed to the status, are also options.


DELETE session probably has the wrong semantics for the way most systems implement sessions and logins. PATCHing it to closed is a better match. POSTing with the user id to a URL for closing sessions is the best fit for how we usually do things. There's a reason why most systems are implementing this with POST instead of PATCH.


> DELETE session probably has the wrong semantics for the way most systems implement sessions and logins.

I prefer to view HTTP method selection based on the logic from the "user side" rather than the implementation from the "system side".

Obviously, though, there are different ways of looking at this, and no One True Way.


> There's a reason why most systems are implementing this with POST instead of PATCH

You mean reasons like browsers not supporting anything but POST and GET?


Well then it's not REST anymore. Your URL should indicate the resource, that's it. Moreover, to say that it's "bullshit" that it would break every REST API is just wrong. That doesn't mean you couldn't change the API to work around it, but it would be broken.


DELETE /sessions/:id


Except that that is almost never the way you would go about logging someone out. Which is precisely the point.


> Except that that is almost never the way you would go about logging someone out.

Its the way I would go about logging somebody out. Why wouldn't you?


This is exactly how I log people out,

POST /_session GET /_session DELETE /_session

(CouchDB API)


That's exactly how I do it. Why wouldn't the session be treated as a resource?


CRUD doesn't cover the whole world, but it's a good start to cover the most frequent 80%. Saying just because it's not 100% let's make all 100% more complex by removing the unifying principle under it makes no sense.


It's not an artificial restriction, it's a design constraint that allows the resulting system to have certain properties that are desirable in some circumstances.

(And GET/POST/PUT/DELETE isn't CRUD.)


Maybe I'm completely off, but in my opinion HTTP verbs are semantically on a lower level. I know that the classic OSI model only has seven layers, and HTTP is in layer seven, but for me, the actual web application using HTTP is in a layer above that.

There are side effects to using those verbs that depend on browser and web server used. For example there may be cases where want to use POST instead of GET even for simple data retrieval, just because you're transmitting a credit card number or other sensitive information and you don't want it to be stored in the web server logs or the browser history. Or the parameters might exceed the maximum length for GET requests. In those cases, it would be a pain to make a semantic distinction between the request verbs on the server level. They should be interchangeable.

Another example is that in IIS 7 you have to jump through quite a few configuration hoops to get PUT and DELETE to work.


For example there may be cases where want to use POST instead of GET even for simple data retrieval, just because you're transmitting a credit card number or other sensitive information and you don't want it to be stored in the web server logs or the browser history.

If you're transmitting any information to the server to be processed/stored, sensitive or not, you shouldn't be using GET at all, per the spec.

GET params are nice for stuff like filtering and parameterizing the rendering of the representation, but surely a CC number is not adequate for such use cases.


I think HEAD is incredibly useful and really critical for things like caching. While you could use GET or POST in place of things like PUT and DELETE, using HTTP headers, you would have to do some work to reap the same benefits you get from HEAD already in retrieving meta data.

For implementing things like a CDN, HEAD requests are absolutely critical. Also most developers probably use it with some high frequency using curl.


If the plan as it seems to be now is to completely ruin the good, clean and nice aspects of HTTP, sure, why not?

Add this to the clusterfuck which is HTTP 2.0.


It is too late to change HTTP semantics - HTTP has to be backward compatible and when whole host of REST semantics depends on the verbs, it simply not possible to change that. Changing a standard fundamentally is something impossible - rather create a different standard and move slowly there.


Getting rid of the unused verbs would probably save a great deal of confusion.

The other alternative is to make it a lot clearer as to what they do and how to use them. But that's not something for the HTTP 2.0 spec.


HTTP/2.0 is meant to have no change to HTTP/1.1 message semantics, and hence its message semantics represent a superset of HTTP/1.1's, so such a change isn't going to happen.


I'd say remove some of the old obscure never used words from the standard. And allow ANY custom operation for extensions and custom API (think java-script and programs).


>PS: It may be worth keeping HEAD just for CORS.

Made me chuckle.


My first web framework (for newLISP) did this and had a nice visual aid from the Ruby on Rails site that showed why it's a good idea: Simplicity:

http://rundragonfly.com/dragonfly_routes

Search for: "Q: Where are the HTTP verbs GET/POST/PUT?"




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: