Let's remove verbs from HTTP 2.0
onebigfluke.com
onebigfluke.com
Also, I feel like "Execution in the Kingdom of Nouns" is semi-relevant here: http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom...
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.
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.
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.
Though specifications aimed at improving at least the hypermedia part of that are starting to gain traction.
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.
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.)
http://en.wikipedia.org/wiki/Representational_state_transfer...
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.
Spot on.
https://dev.twitter.com/docs/api/1.1
its all GET and POST. this is typical.
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)
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
The discussion of the merits of the verbs aside from their frequency of use in APIs is on other subthreads.
Twitter has no concept of edit for a tweet. Is it surprising then that they don't need to use PUT or PATCH?
I posit that if Netscape had implemented PUT, we'd all be talking about the four main verbs, instead of the three main 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.)
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.
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.
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.
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."
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.)
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.
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.
Examples?
nor even behaving like so.
Examples?
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" }'.
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".
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>".)
-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?
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.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.
> 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.
> 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."- 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.
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
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.
> 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.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.
"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.
Since this problem isn't a barrier to using POST to create resources, it shouldn't be for PUT, either.
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.
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...
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.
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.
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.
Read Fielding's dissertation please, or any distributed systems text on the basics of RPC. HTTP is for more than just CRUD websites.
PUT /user/123/following
/user/foo
/user/bar
http://www.other-site-using-standard-formats.com/user/baz
Sigh, if only. /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.FOLLOWERS_FOLLOWERS_FOLLOWING /user/123
FOLLOW /user/123/followers/followers/followingThat's the obvious inevitability of having too many superfluous options. And one of the main thrusts of the article.
Ain't nobody got time for defining semantics.
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.
I explained in more detail here: http://stackoverflow.com/questions/2191049/what-is-the-advan...
POST /_session GET /_session DELETE /_session
(CouchDB API)
Its the way I would go about logging somebody out. Why wouldn't you?
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.
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.
You mean reasons like browsers not supporting anything but POST and GET?
(And GET/POST/PUT/DELETE isn't CRUD.)
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.
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.
For implementing things like a CDN, HEAD requests are absolutely critical. Also most developers probably use it with some high frequency using curl.
Add this to the clusterfuck which is HTTP 2.0.
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.
Made me chuckle.
http://rundragonfly.com/dragonfly_routes
Search for: "Q: Where are the HTTP verbs GET/POST/PUT?"