Feature #9020
Updated by drbrain (Eric Hodel) about 11 years ago
# SUMMARY
I would like to propose adding predicate/query methods to Net::HTTPResponse for testing the status/type of response. For example:
response.ok?
response.not_found?
response.client_error?
response.server_error?
# BACKGROUND
The approach I've most commonly used/encountered for testing the status of a response is to compare with an integer, for example:
response.code.to_i == 200
Subjectively I could say this kind of code is awkward/tedious to type, and not very "intention revealing". More practically/objectively it's a potential source of error. By mistyping the "magic number" it's possible for this expression to "silently fail" and test the wrong status. That would be an easy thing to spot in these examples, but much more difficult to track down within a typical codebase.
Another approach would be to test the type/class of the response object, for example:
Net::HTTPOK === response
Subjectively I would say this doesn't feel very Ruby-ish. More practically/objectively it tightly couples the caller to the implementation details of Net::HTTP, making it difficult to stub or swap in a different library.
# PROPOSAL
I would like to propose adding predicate/query methods to Net::HTTPResponse in order to encapsulate the implementation details of testing for different statuses and to provide a more abstract interface to the caller. For example:
response.ok?
response.not_found?
This is more concise/readable. In most cases it would be easier and "less fiddly" to type out than the existing approaches presented above.
Compared to testing with integers it is one method call instead of three (I'm considering that as better from a readability perspective, not a performance perspective), and it eliminates the "failing silently" issue.
Compared to testing the type/class of the response object it doesn't couple the caller to implementation details of Net::HTTP, so it would be easier to stub or swap-in another library that provides the same interface.
Overall it feels much simpler and much more Ruby-ish.
In addition I would propose adding a few extra methods to test for ranges of statuses, for example:
response.client_error?
response.server_error?
Similar benefits/rationale.
# IMPLEMENTATION
I have already been using methods like this in some gems, and I have created a "proof of concept" implementation which monkey-patches Net::HTTP to test the idea out. Available here:
http://rubygems.org/gems/net-http-predicates
https://github.com/timcraft/net-http-predicates
I can think of various different ways to implement a patch, so if this feature would be accepted into ruby-trunk I would welcome suggestions/guidance on a preferred implementation.
These changes would be backwards compatible and straightforward to provide as a backport, either in the backports library/gem or as a standalone gem.
# DISCUSSION
Before discussing how to implement this patch I would like to get people's thoughts on the idea/proposal, and some indication of whether this could be accepted into ruby-trunk (or not). If it would be accepted I'm happy to write/submit the patch itself.