-2

This is a question which I have had in the back of my mind for a significant length of time, but never found an answer to, and never thought to directly ask - until today.

I am interested to understand why HTTP supports multiple different methods, GET, PUT, POST, etc.

My thoughts on this are:

  • http methods are a way of calling remote functions via across a network
  • in other words when a client application makes a reques to a remote server, if there were no network seperating them, then the client could just as well call a function within its own process, on the same machine
  • if the above point isn't immediatly clear, consider that a client and server application can run on the same host communicating via localhost, if we removed the networking layer, it would work instead by the client calling a function which belongs to the "server code" - both the client and server would however be part of the same, single process

The http protocol supports routes, which are analagous to function names inside a namespace. Some http requests can have parameters attached to them, or a more complex body. This, combined with a response, provides a way to exchange data bidirectionally.

The analogy with a function is quite transparent - a function is called with some parameters or "data" in general, and returns some other data via a return value.

So why does http support multiple methods? Is this just a historical accident?

Of course, not all http requests do the same thing, however in principle there is no reason why it would not be possible to define a "super" http method which can do everything each presently existing method can do. (At least as far as I am presently aware.)

In other words, GET (or any other method) could have been defined as a general data exchange method where some data is passed in and some other data is passed back out. This would seem to be a general method, which could be used for any purpose.

7
  • "a way of calling remote functions via across a network" - superficially, you could view things that way, but there is a bit more to it than that; the Web is not just you and the server, there are all kinds of things happening in between - see the answer by VoiceOfUnreason here, and also take a look at an overview of design constraints of the web here, and maybe the §Technical Overview here. It's these constraints that HTTP was designed to meet. Dec 2, 2023 at 17:05
  • Hopefully, that answers the "why" behind it. That said, could it be done in some other way - yeah, probably, but you'd still have to provide facilities to satisfy those design considerations, it would just look a bit different. Dec 2, 2023 at 17:08
  • "The http protocol supports routes, which are analagous to function names inside a namespace" – Huh? I don't see what message routing has to do with "function names inside a namespace". Dec 2, 2023 at 22:53
  • @JörgWMittag /users/create is different from /users/delete. In the function analogy you end up with users being a namespace, and create and delete being function names. Dec 3, 2023 at 20:36
  • This has nothing to do with message routing. Message routing refers to which path the HTTP message (request or response) takes through multiple proxies and caches between the client and the origin server. What you are referring to is how the server application interprets the path component of the request URI, which is not part of HTTP, and crucially, has no well-defined semantics. There is no guarantee that your application and my application interpret those paths the same. There is also no guarantee how my application interprets those paths. I could choose to interpret a request to … Dec 3, 2023 at 22:08

3 Answers 3

10

there is no reason why it would not be possible to define a "super" http method which can do everything each presently existing method can do

Such a method already exists: POST has no safety or idempotency guarantees, and no well-defined semantics other than "the server will interpret this in some way, and something may or may not happen as a result". Because of these incredibly vague semantics, POST can be used to emulate the semantics of all other methods of the "classic web".

If you don't want to restrict yourself to the "classic web", then the method you are looking for is CONNECT. It allows you to open a bi-directional TCP connection to an arbitrary TCP port on an arbitrary server. It doesn't get more generic than that.

You state [bold italic emphasis mine]:

GET (or any other method) could have been defined as a general data exchange method where some data is passed in and some other data is passed back out. This would seem to be a general method, which could be used for any purpose.

That is exactly the problem. Since it could be used for any purpose, only the processing application knows what it means, which guarantees exist, which requirements must be fulfilled, etc.

A cache has no way of knowing whether or not it is allowed to return a cached copy of the request. A proxy has no way of knowing whether it can repeat a request. A crawler has no way of knowing which resources it can safely retrieve.

In contrast, the different HTTP methods have different, well-defined semantics associated with them.

In particular, there are two kinds of high-level semantic guarantees the HTTP specification makes:

Safety

The simple definition of safety is that safe methods cannot have side-effects. This is only a simplified definition, however. Taken literally, this would mean that the server would not be allowed to log requests, which is obviously ridiculous.

A better way to state it would be the client cannot be held responsible for side-effects. This means the server is free to execute side-effects, but if something goes wrong because of these side-effects, it's the server's fault and server's problem, not the client's.

The way the specification states it is

[… ]the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. Likewise, reasonable use of a safe method is not expected to cause any harm, loss of property, or unusual burden on the origin server.

Methods

The safe methods are

Idempotency

Idempotency is a weaker guarantee than safety. It does not guarantee that there are no side-effects, but it does guarantee that repeating the same request will only perform the side-effect once. Or, put differently, the effect of multiple identical requests is the same as the effect of a single request.

Similar to the situation with safety, this only applies to side-effects that the client expects and explicitly requested. The server is free to execute additional side-effects, but the client can't be held responsible or those effects.

Or, as the spec puts it [bold italic emphasis mine]:

A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. […]

Like the definition of safe, the idempotent property only applies to what has been requested by the user; a server is free to log each request separately, retain a revision control history, or implement other non-idempotent side effects for each idempotent request.

It should be obvious that safe methods are also idempotent since executing no effect multiple times is still no effect.

Methods

The Idempotent Methods are

No guarantees

All other methods are neither idempotent nor safe:

You cannot make any assumptions about their behavior.

What does this gain us?

The semantic guarantees allow clients, caches, and proxies to make certain assumptions and thus perform certain optimizations based on those assumptions.

For example, in case of a network failure, a client or proxy can blindly retry an idempotent request without having to check whether the previous request failed or succeeded. A web archiver or search engine indexer can blindly send safe requests and is guaranteed that nothing bad can happen.

This is also important for the behavior of the back button in a web browser: depending on the method, the browser can either fetch the previous resource from cache, re-request it from the server, or it needs to ask the user for permission to re-send a non-idempotent request.

Caching

In addition to the two guarantees above, certain methods also have specific, and different, rules for caching.

For example, a cache must invalidate the target URI after a successful unsafe request. There are also special caching semantics for HEAD.

POST is not allowed to be cached unless it is explicitly annotated with explicit freshness information. A cached POST request can only be used to satisfy GET and HEAD requests but not POST requests.

The architecture of the web

http methods are a way of calling remote functions via across a network

This is very much not what HTTP is about!

If you want to know why HTTP is designed the way it is designed, there is no better resource than Roy Thomas Fielding's 2000 PhD dissertation Architectural Styles and the Design of Network-based Software Architectures. Fielding has been involved with the web since 1993, and was deeply involved in the development of the URI, HTML, HTTP/1.0, HTTP/2, and HTTP/3 specifications, among other web-related things.

The thesis is not a specification of HTTP. The thesis evolved together with the web: the thesis is both informed by the web and at the same time, it forms the basis of the web. The thesis itself is stated more generally than just the WWW, it is a general description of the problems that a large-scale information system needs to solve and what architectural constraints must be applied to solve those problems.

Throughout the thesis, Fielding develops an architectural style he calls Representational State Transfer (REST)

Note that "large-scale" here means truly large-scale, and in multiple different dimensions:

  • Geographical dimension: spanning large distances across multiple continents, potentially the entire Earth and even beyond.
  • Temporal dimension: spanning large timescales, beyond a single human generation, but also spanning multiple technological generations.
  • Organizational dimension: spanning multiple, potentially non-cooperative and un-coordinated, organizations.
  • Trust dimension: crossing multiple trust boundaries.
  • System size: millions of servers, billions of clients, potentially trillions of resources, quadrillions of messages.
  • Distributed, de-centralized.
  • Heterogeneous servers, clients, networks, Operating Systems by independent, non-coordinated vendors.

It is very important to understand this: the design of REST and the web (specifically HTTP and URI) is very much driven by those requirements. If you are building a system that is not a distributed information system, spanning multiple continents, organizations, networks, and technologies, expected to run a hundred years, with billions of users, then you probably don't need an architecture like REST or HTTP.

Web vs. RPC

Coming back to your statement:

http methods are a way of calling remote functions via across a network

There is an entire sub-section in Fielding's thesis titled 6.5.2 HTTP is not RPC [bold italic emphasis mine]:

People often mistakenly refer to HTTP as a remote procedure call (RPC) mechanism simply because it involves requests and responses. What distinguishes RPC […] is the notion of invoking a procedure on the remote machine, wherein the protocol identifies the procedure and passes it a fixed set of parameters, and then waits for the answer to be supplied within a return message using the same interface. […]

What distinguishes HTTP from RPC isn't the syntax. It isn't even the different characteristics gained from using a stream as a parameter, though that helps to explain why existing RPC mechanisms were not usable for the Web. What makes HTTP significantly different from RPC is that the requests are directed to resources using a generic interface with standard semantics that can be interpreted by intermediaries almost as well as by the machines that originate services. The result is an application that allows for layers of transformation and indirection that are independent of the information origin, which is very useful for an Internet-scale, multi-organization, anarchically scalable information system. RPC mechanisms, in contrast, are defined in terms of language APIs, not network-based applications.

That's the fundamental difference: a remote procedure call has semantics that are only understood by the client and the server. Whereas HTTP methods have semantics that are also understood by all "middleboxes" such as proxies, caches, and application firewalls, and generic clients such as browsers and crawlers.

1
  • 2
    This is a really great and informative answer. Thanks a lot. It makes a lot more sense to me now why there are disctinct verbs. Dec 3, 2023 at 20:33
4

You're looking at this from a ahistorical perspective - looking at the HTTP protocol as it is used today as a protocol for encoding RPC calls for web-based applications. However, this isn't what the protocol was made for.

The HTTP protocol was designed for, well, hyper-text transfer, as its name implies. It's a protocol designed to GET web pages from a server to display in a browser. HTTP/1.0 added POST and HEAD to support form submission and optimizations, and HTTP/1.1 added PUT and DELETE and other verbs, signifying the shift from a simple web-page delivery protocol to one more suited for application development, with semantics (often called REST semantics) dealing with changing the state of resources on the server.

This concept - of the HTTP methods mutating the state of resources - is not a general-purpose RPC protocol for "calling remote functions across a network". They are, as the protocol specs define, methods for retrieving, sending and manipulating resources on a server. That's what HTTP does. That's what it was designed for, and that's what the world of browsers grew up knowing how to do.

But when the internet and browsers became ubiquitous and people wanted to use them to develop network applications, they wanted, as you say, a mechanism to perform remote function calls across the network. Because HTTP was already there - supported by browsers, traversable by firewalls, allowed by network admins - people simply started modeling their RPC calls on top of HTTP. The route http://my-server/my-resource/create is mapped by my server backend to the CreateMyResource function, and so forth. The call can be modeled as an XML payload specifying the RPC method with a lot of extra metadata and annotations for a thousand enterprisey backend systems (SOAP), or a simple JSON payload POSTed to an endpoint (so-called REST, even though it usually isn't), or ProtoBuf payloads over an HTTP/2 bidirectional streaming connection (gRPC), but these are all RPC mechanism invented after HTTP. They tend to use the HTTP methods for their semantics (GET for Get/List calls, POST for Create/Update, DELETE for Delete), but usually not religiously (PUT isn't popular in most frameworks), because they inherited it, and are constrained by it (GET calls have a query string, but no body, for instance), but don't follow it religiously, because it's just an artifact of the underlying transmission protocol.

8
  • Would you say it was fair to conclude that the inclusion of the different http verbs was uneccessary - everything you have described above regarding the history could have been accomplished with no verbs and by passing parameters, even if those parameters formed part of a more complex message inside a http body. I don't disagree with your answer, I'm sure the history is indeed accurate, but that doesn't fully explain why there exists a GET and a POST. Unless the reason is that the original design of http isn't quite as sensible as it could have been... Dec 2, 2023 at 18:28
  • ... For example, the GET verb was the first and only verb. But there need not have been a "verb" at all - and if there hadn't been it is probably the case that the concept of verbs would not have existed at all. Dec 2, 2023 at 18:29
  • @user3728501 No, you can't PUT or POST with GET. A GET generally doesn't have a request body for additional data. URLs are quite limited in length (in practice <4KB). GET requests also have assumptions around caching that make them unsuitable for modifying operations, even though these assumptions were only formalized much later (I think HTTP/1.1).
    – amon
    Dec 2, 2023 at 18:38
  • @amon So this is the point of my question. You could have used PUT or POST and GET with a single verb (doesn't matter what it is called) by providing an additional argument of piece of data as part of a request body. There's no reason why this couldn't have been done as far as I am aware. Is this isn't the case - why not? Dec 2, 2023 at 19:28
  • 1
    Well, I think the historical perspective answers that. It's a protocol designed to fetch webpages and post form data, and the verbs as the core functions of the protocol make sense (including less-common ones like HEAD or OPTIONS). Later, it was coopted as the general purpose transport mechanism for RPC, which naturally means there is some mismatch and impedance, but the pain it causes isn't nearly as large as the pain of trying to switch off of HTTP for RPC. Dec 5, 2023 at 16:13
1

The HTTP protocol specification answers this question:

https://www.w3.org/Protocols/HTTP/Methods.html

GET and PUT can be seen as analogous to accessing a hash map where the URL is the key and the body is the value.

DELETE is needed to remove an entry from server (or hash map in this analogy).

The PUT method specifies that the URL must already exist so the POST method becomes necessary, in order to create new URLs on the server.

TL;DR - The HTTP methods are defined as the actions that can be taken against a URL - this is logical since this is the view the client has (the processing on the server is a black box to the client).

1
  • All of those operations could have been done with a single verb, or with no verb, and some additional parameters or data passed in a body. This is the reason for my question. Dec 3, 2023 at 20:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.