Having professionally developed in Ruby for some time now, I find this (maybe a strong word) inspirational. It shows just how more diligence can be done when choosing a dependency. It’s easy (and I’ve gotten used to it now) to choose what’s popular and it’s easy to assume those Github stars have done the hard thinking.
nginx proxies will retry HTTP requests. This is undesirable and scary because – when you make a request, often you expect it to happen just once! What if your GET request means “execute this trade”? Then it shouldn’t just get randomly retried – you want control over that!
How about making perhaps critically non-idempotent endpoints use an HTTP method that’s not explicitly intended for use by idempotent resources, instead of trying to control the behaviour of all the clients doing what the spec seems to allow them to do?
This presumes you have control over every endpoint you might want to contact with such a library, which is pretty often not the case. I know plenty of APIs exposed by services which do put non-idempotent functions on GET. The real world isn’t an RFC spec.
Following that argument, though, no contract and no standard has any value and compliance is a myth.
Lots of the internet relies on GET being idempotent and it doesn’t break.
Yeah, sure. But remember, we’re trying to use this to consume possibly broken services which we have no control over. The article author isn’t asking you to throw out the notion of standards, she’s asking for the ability to configure it away from a sane default, when dealing with a non-sane service:
it makes a lot of sense for a web browser to retry, and perhaps less sense for a library you’re calling from your code to automatically retry, without the ability configure it.
Consider the basic case of a web browser tab that needs to be refreshed. If it is a GET then most browsers assume all is well and we can visit that URL again. Apart from showing a “Are you sure you want to do this?” the browser can’t really do anything to mitigate the problem of non-idempotent GET calls. That part of the world will just have to burn until someone programs it to spec (Which for very basic HTTP functionality such as it, it isn’t very hard).
Note that “The HTTP Gem” (a.k.a. http.rb) also natively implements HTTP in Ruby, using the http_parser.rb gem’s native code parsers to parse the response: