- The first line of an HTTP request has its own format (space-separated-ish), and mixes method and URL path.
- The URL path in that first line has its own format and weird escaping, and mixes one path with zero-or-more key value pairs.
- The headers have their own format.
- The body has its own format.
Most (all?) HTTP libraries for clients and servers abstract all that mess away into a neat object that could be easily represented in JSON (or bencode if you want something simple-ish while supporting binary data), but it's like using a nice program while knowing it's written in C[1].
Of course, JSON has its own problems, but in that case at least we only need to deal with the problems of one format that supports with proper nesting, not 4 different weird formats masquerading as one.
[1]: Disclaimer, I don't like Rust, so don't take this as a RIIR thing.
EDIT: To be clear, I don't agree with how Bob misuses HTTP in your example. I just find it sad that we're locked into this weirdly complex protocol.
Many of these choices are there for backwards compatibility and reuse. I can totally understand why.
An HTTP body has no predefined format. It can be anything. It can be a stream (HTTP into WebSocket upgrade, for example). It is the media type that defines how the body should be interpreted.
HTTP requests are meant to be used before they are fully transmitted, and are formtted in a way to leverage socket communication. JSON, on the other hand, needs the whole document to be read before it can be safely interpreted.
HTTP has more moving parts, but it also does so much more. These two aren't even comparable, they're not in the same layer.
I understand the urge to "improve" on all of this "legacy", however, one must consider how much was built upon these standards and if there's anything real to gain by changing them.
I would love if we could improve on HTTP - even just clearly separating protocol from application would be so great. Maybe dropping some cruft, like the accept headers and so on.
But yes, doing that is total folly.
The separation is your choice. It is not enforced, as this would require limitations that are not worth having.
You can totally drop accept headers if you write your own client and server implementation. HTTP works fine without them. The web as a living organism, not so much.
But hey, we don't need content type negotiation, right? XML will reign forever, mp3 is the ultimate audio format. It's not like new codecs and document types appear all the time and some kind of underlying architecture has to reserve space for that kind of change.
As I said, if you're writing your own client and server, you don't need Accept. You probably use just one homogenized content type.
Using `?format=json` is not offensive. It won't mess up some cache layer like improper status code semantics, so I don't really care that much about these if I see it. I wouldn't block a PR on that.
The overall web on the other hand, is supposed to be made of many different client and server implementations. Your browser still relies on Accept headers for displaying images, detecting language, uncompress gzipped responses, resuming paused downloads, showing that JSON API in a nice UI when you open in a dedicated tab, so many things.
To me, it makes sense to leverage the same content negotiation ideas for home grown stuff, even if only one content type is being used.
It starts being a problem if you're working on microservices, and one of them uses `.json` while other uses `?format=json`, made by different teams. The standard is the obvious solution. Instead, they'll either create inefficient clients full of complexities or fight until one of the workarounds prevail. So much easier to follow the standard.
Ah yeah no disagreements there. Better something that already works and is widely used with good ecosystem around it, than risk an xkcd 927 situation.
I understand that the people at the time (presumably) did it the best they could with the information and knowledge they had at the moment, while keeping backwards compatibility.
I only know a bit about HTTP/0.9 and can see how we moved from that to what we have today. I just find the current situation sad.
Like when something only supports ASCII, or only supports IPv4, or assumes I only have 1 CPU thread. Or like when some binary file is encoded in base64 before being sent over the network, only to be decoded on the receiving end. Stuff like that.
But I only feel that way thanks to having the huge benefit of hindsight and modern technology.
If ASCII is obsolete compared to Unicode, IPv4 is obsolete compared to IPv6, and single threadness is obsolete compared to multi-threading (I don't think that is a valid comparison, but let's go with it), then which standard makes HTTP obsolete?
HTTP/2 or HTTP/3 don't look like that, anymore. The HEADERS frame is just a key-value map where the reserved keys :method, :scheme, :path etc are used for the previously top-level message elements.
- The first line of an HTTP request has its own format (space-separated-ish), and mixes method and URL path.
- The URL path in that first line has its own format and weird escaping, and mixes one path with zero-or-more key value pairs.
- The headers have their own format.
- The body has its own format.
Most (all?) HTTP libraries for clients and servers abstract all that mess away into a neat object that could be easily represented in JSON (or bencode if you want something simple-ish while supporting binary data), but it's like using a nice program while knowing it's written in C[1].
Of course, JSON has its own problems, but in that case at least we only need to deal with the problems of one format that supports with proper nesting, not 4 different weird formats masquerading as one.
[1]: Disclaimer, I don't like Rust, so don't take this as a RIIR thing.
EDIT: To be clear, I don't agree with how Bob misuses HTTP in your example. I just find it sad that we're locked into this weirdly complex protocol.