def handle_thing(thing):
r = urllib.request.Request(url='example.com',
data={'stuff': 1})
return urllib.request.urlopen(r)
Just one example.I know the tooling has improved somewhat since REST has become extremely common, so this is less of an issue now than it used to be (for example, most people use the Python requests module now, which makes it harder to use the wrong method (though many other HTTP libs still have the older urllib-style design)), but it's still annoying in principle. Combine with the fact that people tend to have different ideas about what the HTTP verbs and response codes mean, and it's pretty yucky.
Compare with Thrift, where you define an interface, list the possible exceptions, and generate stubs that auto-handle all of this communication exchange for you. All you have to do is make sure that you're calling the correct function, which should be pretty obvious.
This differs from setting the correct method in the HTTP headers in a couple of ways: first, HTTP clients usually assume a default method of GET. With a different protocol, there is no default "method", your action has to be defined somewhere. There will be no assumption (unless you code something implicit like this on top).
Second, a more conventional method has increased code locality, meaning the code that affects the operation is likely to be in the same source file/area. You'll normally be calling an ordinary function name like SaveThing inside the application logic flow, and it will be easier to debug, easier to realize the problem, etc.; the operation to perform is not tucked away in some other contraption that affects the headers.
Is it possible to design REST codebases so that such errors are hard to cause? Sure. But why do it the REST way and make it harder on yourself?
It should be just as easy to see what function you're asking the API to perform on a resource as it is to see what you're sending it. The operation I want to perform is an intrinsic part of what I'm doing. There's no reason to separate it and make it hard. I'd even prefer url-based actions, like example.com/string_save, because then at least the resource and operation are defined in the same spot.
A simple JSON envelope that has an "operation" key separate from a "data" key would make this easy, but then it's not in your header anymore, so it's not "real REST".