Hi there, and thanks for all the fantastic work that we’re getting to use.
We’re in the process of writing a library to access popular shipping providers - think
ActiveShipping, but somewhat more modern and not archived. Here’s the gem if you’re interested (no need to read the gem, the question is entirely in this post):
We’re making heavy use of the
Result monad to wrap successful or unsuccesful API calls.
The API goes somewhat like this:
>>> ups_service.find_rates(shipment) Success([rate1, rate2, rate3])
Now, for both
Failure, my colleagues are asking for debugging information because shipping APIs are complex and sometimes unpredictable, and it takes a lot of inspection to find out what went wrong. They would, specifically, like the
shipment object that was passed in as well as the request that was generated as well as the response obtained from the provider.
Currently, we have another object around the rates array that does this, so that we can do this:
>>> result = ups_service.find_rates(shipment) Success(rates_result) >>> result.value!.rates [rate1, rate2, ...] >>> result.value!.original_request my_request
However, I believe it would be more ergonomic and nicer to be able to access the debugging info directly on the
>>> result = ups_service.find_rates(shipment) Success(rates_result) >>> result.original_request my_request
Is this possible? I’ve tried subclassing
Failure, but that seems to be pretty hard as all the syntactic sugar (constructor functions etc) need to be adapted as well, as the
initialize signature changes. I’m also not sure whether specialized
Result monad would play well in the rest of the Ecosystem. I was thinking of adding
to_dry_result to ameliorate this.
How do you go about these kinds of things? There’s one value that is really the thing you want, and a bunch of less important info that should go in the result as well.
What I’ve seen in the docs is using Arrays or Hashes for the
value that’s passed into the monad. That, however, is similar to the result container presented in the first example.
Caveat also: I’m not new to Ruby, but I am pretty new to functional programming and the Dry ecosystem. It’s entirely possible there’s a much better way of achieving what I want: An ergonomic API interface that lets library users get quickly at what they need.
Thank you for reading, and again: Thank you, I love your work!