Ultimate Guide To 9 Common HTTP Methods

We tend to take HTTP methods for granted. In the API development space, methods are akin to the alphabet – often used, seldom considered. API developers typically only use GET, PUT, or POST, but the official HTTP Request Method registry lists 39 total HTTP verbs, each providing a method for powerful interactions. In this article, we review 9 of the most common ones.

Below, we review 9 standard HTTP methods and do a bit of a deep dive into what each method does. For our examples, we’re going to use the PetStore API to provide some sample API calls which demonstrate these methods. Keep in mind that API methods can be used in a wide variety of ways, so your use case may differ in function. Nonetheless, these methods are well-defined, and as such, the examples given here are some of the most commonplace.

Resource Retrieval Methods

Perhaps the most obvious of the methods we’re going to discuss today, GET and HEAD are designed to retrieve a resource in a particular way. This is some of the most commonly understood functionality, as well as some of the most commonly used.

GET

The GET method is designed to request a specific resource. In essence, it literally “gets” the resource in question, and is pretty limited to just that action. GET requests should only retrieve data, leaving other methods to perform the other transformative actions.

Example

In this example, we’re going to issue a GET request to see the current status of a specific animal in the PetStore API using curl.

Request:

curl -X GET "https://petstore.swagger.io/v2/pet/10" -H "accept: application/json"

Response:

{
  "id": 10,
  "category": {
    "id": 0,
    "name": "pudle"
  },
  "name": "doggie",
  "photoUrls": [
    "string"
  ],
  "tags": [
    {
      "id": 0,
      "name": "string"
    }
  ],
  "status": "available"
}

HEAD

HEAD is an interesting method in that it mirrors some functionality of another METHOD while unlocking additional possibilities. HEAD requests a GET response from a given resource, but with the response body excised. While that may seem overly simplistic, it allows greater flexibility and power for other API extensions – for instance, you can pass the headers of a resource to another request in an attempt to mimic a different requesting environment or situation, which is extremely helpful for testing and troubleshooting.

Example

Let’s do issue a request to see only the headers of the given entry.

Request:

curl -X HEAD "https://petstore.swagger.io/v2/pet/10"

Response:

access-control-allow-headers: Content-Type, api_key, Authorization
access-control-allow-methods: GET, POST, DELETE, PUT
access-control-allow-origin: *
connection: close
content-type: application/json
date: Sun, 08 Dec 2019 16:10:08 GMT
server: Jetty(9.2.9.v20150224)

Resource Modification Methods

There are many methods that can change the resource fundamentally. These methods can include the placement of a resource, the replacement of a targeted resource, and even the updating of attributes about the resource.

PUT

PUT is somewhat the polar opposite of GET. While GET requests a specific resource, PUT places that resource in the remote directory. It should be noted that PUT assumes either the resource does not exist or the resource is fine to be overwritten – when using PUT, all representations of the target resource will be replaced by the payload.

Example

We’ve received a new puppy in the PetStore! Let’s update our data on the backend to reflect this.

Request:

curl -X PUT "https://petstore.swagger.io/v2/pet" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"id\": 100, \"category\": { \"id\": 0, \"name\": \"shiba\" }, \"name\": \"inu\", \"photoUrls\": [ \"string\" ], \"tags\": [ { \"id\": 0, \"name\": \"string\" } ], \"status\": \"available\"}"

Response:

{
  "id": 100,
  "category": {
    "id": 0,
    "name": "shiba"
  },
  "name": "inu",
  "photoUrls": [
    "string"
  ],
  "tags": [
    {
      "id": 0,
      "name": "string"
    }
  ],
  "status": "available"
}

PATCH

PATCH is designed to partially modify a targeted resource. In other words, while PUT places a resource in the target service, PATCH modifies that resource, as opposed to replacing it. This is a good way to update files or versions.

Example

Our new puppy has been adopted in its first day! We’ll need to update the resource in order to reflect this on the API.

Request:

curl -X PATCH "https://petstore.swagger.io/v2/pet" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"id\": 100, \"category\": { \"id\": 0, \"name\": \"shiba\" }, \"name\": \"inu\", \"photoUrls\": [ \"string\" ], \"tags\": [ { \"id\": 0, \"name\": \"string\" } ], \"status\": \"unavailable\"}"

Response:

{
  "id": 100,
  "category": {
    "id": 0,
    "name": "shiba"
  },
  "name": "inu",
  "photoUrls": [
    "string"
  ],
  "tags": [
    {
      "id": 0,
      "name": "string"
    }
  ],
  "status": "unavailable"
}

DELETE

DELETE is the most clear-cut method on this list because it does exactly what’s on the tin – DELETE deletes a targeted resource. The typical response for a deletion method is simply to reply with an “OK” status – either the resource was deleted, or it was not.

POST

POST affects the related resources attached to a targeted resource. POST allows an API to submit an attribute or entity to a given resource; in practice, this means the targeted resource receives a subordinate resource that is part of a larger collection. As an example, one use of POST would be to add an image to a resource – in the case of PetStore, we might want to add a photo that can be used to help adopt our shelter puppies.

Request:

curl -X POST "https://petstore.swagger.io/v2/pet/10/uploadImage" -H  "accept: application/json" -H  "Content-Type: multipart/form-data" -F "file=@background.png;type=image/png"

Response:

{
  "code": 200,
  "message": "additionalMetadata: null\nFile uploaded to ./background.png, 63705 bytes"
}

OPTIONS

The OPTIONS method changes the different communication options held by the target resource. This can be used to both open up more channels of communication and lock them down – for this reason, the OPTIONS method should be considered akin to a faucet which can be opened and closed with relative granularity.

Resource Environment Methods

Not every change to a resource has to be a change to the resource contents. There are two core methods that interact more with the environment of the resource than the resource itself.

TRACE

TRACE is a method that carries out a message loop-back test. This test allows one to take a look at the path to the targeted resource, identifying potential points of failure. This is a highly powerful tool, simple as it may be since it mirrors the essential pathing of a resource.

CONNECT

CONNECT is a method that creates communication with a resource rather than directly interacting with said resource. CONNECT establishes a tunnel to the server which holds the targeted resource.

Idempotency – When Do You Need Idempotent Requests?

What is Idempotency?

While idempotency is a complex enough topic to warrant its own piece (we’ve written about it extensively here), the concept is closely coupled with HTTP methods and bears quick discussion here. Idempotent requests should produce the same result time after time, regardless of the environment. In other words, an identical request should issue an identical response consistently. This identical response should be in form rather than in output – the form and nature should remain the same, even if the underlying data being fed forward is not.

To quote our original piece on this topic:

“A good way to frame your understanding of this concept is to think of each functional call as asking a question in another language. When you ask someone what time it is in Spanish – “¿que hora es?” — the answer to that question can change depending on the time of day. This would be a changing value.

The way in which you expect the response, however, does not change – just because it is 4pm, the person responding is not going to start using “lemons” as a measurement of hours, or respond to you in French. Each response will be structured in the form, syntax, and grammar that you expect – and no matter how many times you ask, it will always be in Spanish. This is the function of the call. One can imagine the chaos that might ensue if a person constantly switched between Spanish, French, German, and English depending on the time of day and what is being asked – in this situation, it would be impossible to form any effective, coherent expectations.
The same is true in the API space. The functional call should not be different with each request, but instead should return in a known, expected way, regardless of how different the response value might be.”

We should note that idempotence is different from safety, which is a similar term used quite commonly when discussing HTTP methods. Safe methods simply do not alter the state of the server. It is possible to be idempotent as well as safe, but it’s also possible to be one and not the other. The following infographic displays which methods are idempotent and which ones are safe – we can see quite easily that GET and HEAD, the only methods that interact with the resource without actually altering the contents of the resource, are the only “safe” methods, even though they are also idempotent. On the other hand, POST and PATCH, two methods that result in very different output each time they’re used, are not safe.

When Should Methods be Idempotent? When Should They be Safe?

Methods (and operations involving them) exist for a very specific purpose, and both the idempotency and safety of them should be closely coupled with the method chart as laid out above. There are some very clear cut cases where we can say a method absolutely should result in the same thing consistently – for instance, GET and HEAD are very much methods concerned with getting information, and not with altering information. In these cases, the method application is pretty cut and dry. What about the middle ground?

PUT and DELETE are both cases in which the result is the same time and time again, but the functional outcome is not. GET and HEAD should result in exactly the same outcome on a resource as long as that resource has not changed – PUT and DELETE, however, result in an outcome that essentially confirms the state of a new resource or entity. PUT places a resource somewhere, and DELETE removes that resource – as such, the idempotency here should be either a failure or success state. In other words, confirmation and outcome are different here.

POST and PATCH, however, by design should not result in identical calls because of what they do. Both of these change the content fundamentally and could respond differently depending on whether the attribute being changed currently exists or not. As such, they are not idempotent, and if they were, they’d be unable to do what they’re designed to do.

Of our entire list, only two methods are actually safe – GET and HEAD. These two methods neither change the state of the resource nor result in differences as long as the resource stays unchanged, and as such, are alone in their safety.

Conclusion

HTTP methods drive the fundamental API interactions that we see day in and day out. Understanding these methods, their idempotency, and their safety is a key step towards understanding the API space with a substantially deeper appreciation.

Common assumptions and “general understanding” have led some of these methods and related terms to be misunderstood, misused, and misapplied. However, with a few simple base concepts, the concepts can be readily learned and understood.

What do you think about these methods? Another argument around them is whether they’re called “methods” or “verbs” – we’ve chosen methods here, but we’re interested to hear what you call them. Let us know below!