DEV Community

Discussion on: Explain HTTP Verbs like I'm Five

Collapse
 
appeltel profile image
Eric Appelt

Rule 1: Very few people actually know the rules

The most important thing to know about using HTTP in practice is that it is like the board game Monopoly: it comes with a very specific book of rules that almost nobody follows completely. There are some rules in Monopoly that most people follow, like how you roll the dice and go around the board, but a lot of details are simply made up. For example, in most households there will be some reward ($500 or more) for landing on the "Free Parking" space. The rules say that nothing happens when you land there, but no one follows the actual rules.

HTTP verbs are governed by the official "rule books" RFC7231-sec4.3 and RFC5789.

Now part of the reason that no one completely follows the rules is likely laziness on the part of API developers, but another important reason is that they don't really apply terribly well for a lot of things that people want to do. This is similar to Monopoly, where people really just want to have fun. Getting $500 when you land on "Free Parking" is much more exciting than nothing happening, so even if you tell people what the rule says they should do, they won't follow it.

There are two rules about HTTP verbs that are almost universally followed in my experience, they are good rules, and make sense in nearly any context:

  • GET - this only retrieves information and doesn't change anything on the server. It's completely safe to GET and you shouldn't ever break anything by doing so. In terms of "look, but don't touch", a GET request is just looking.
  • POST - this typically can and will cause changes to happen. In the "look, but don't touch" adage, with a POST you are touching.

Rule 2: The rules are rules for managing documents

The rest of the rules don't always make much sense because people tend to use HTTP for things it wasn't originally intended to do. The point of HTTP is to publish hypertext documents and send them around the network. So the rules talk about "resources" which if you aren't shipping around documents doesn't always make a whole lot of sense. I think this is really why the verb meanings seem more confusing than they are.

So in order to understand the rules, lets take a JSON grocery list: {"groceries": ["milk", "eggs", "apples"]}. Think of this as your document, published at the URL http://www.myserver.foo/grocery_list.json.

  • A GET to http://www.myserver.foo/grocery_list.json will retrieve the document {"groceries": ["milk", "eggs", "apples"]}, and give you a status code of 200 (meaning OK), along with some header information such as the content-type which is json.
  • A HEAD to http://www.myserver.foo/grocery_list.json will give you the status code and header information that a GET would have provided, telling you that the document exists and has a type of json, but doesn't send the actual document.
  • A PUT to http://www.myserver.foo/grocery_list.json will replace your grocery list with the document you send in the request body. For example, if I PUT {"groceries": ["grapes", "bananas"]}, then the next time someone does a GET, they will get my new list {"groceries": ["grapes", "bananas"]} back. The contents of the document are completely replaced. I can update an existing document like this or even create a new one if the server allows it.
  • A DELETE to http://www.myserver.foo/grocery_list.json removes the document. A subsequent GET request will return a status code of 404 NOT FOUND.

Now for the POST command, what it does depends on the additional rules that my server and API allows. For example, my grocery list API might allow you to post a JSON body of {"add": "food-item"} or {"remove": "food-item"} to update the existing list. So with these rules I could do the following:

  • A POST to http://www.myserver.foo/grocery_list.json with a body of {"add": "bananas"} would modify the document so that a subsequent GET would then return {"groceries": ["milk", "eggs", "apples", "bananas"]}.

Note that a POST can also modify multiple documents, not just the one specified by the URL. Sometimes a POST can be used to bulk modify, create, or delete multiple documents in a single request.

There are other methods, but those are the most common in my experience. If you think in terms of a url pointing to a document called a "resource", then you can make better sense of the RFCs.

Rule 3: Everyone tends to make up a few of their own rules

I think HTTP is a nice and extremely convenient protocol, which along with the popularity of web browsers has led to it being used to do things other than manage documents. People write APIs to allow you to POST to do all sorts of things, like buy airplane tickets, or even image a new webserver. Its not always easy to think about these remote procedures in terms of "documents" so the rules get muddled, and often only GET and POST gets used in a meaningful way.

As a result of the popularity of HTTP in doing things other than transporting documents, people tend to not follow the rules even when they are transporting documents. I see a lot of "house rules" in HTTP APIs where PUT is used to create a document, and POST to update a document (or maybe the other way around), even though PUT is really for when you are sending the entire document, and POST is for when you are sending instructions for modification. The best thing to do is read the API you are using. If designing an API, I think it makes sense to try to follow the actual RFC rules as best as possible. The more you follow the HTTP specification, the more clients will be able to understand your API without having to read lengthy documentation.

If the verbs don't make any sense for what you are doing when designing an API, you can always use GET to retrieve information, POST to make changes, and document carefully how they work in your API.

Collapse
 
carywreams profile image
Cary Reams

HTTP verbs best thought of as tools to manage documents...

So does that make the RESTful approach a practice for using HTTP verbs to manage those documents ?