Open elShiaLabeouf opened 1 year ago
Hi @elShiaLabeouf, wow, you have lots of ideas, I like that! :green_heart:
Regarding your specific requirement, my suggestion would be to enhance Operation::Result
, which is the actual object exposing #success
and #failure
. There is no need to change deeper gems (in my understanding), or am I wrong here?
One important thing to keep in mind is that calling operations is a concept that will happen in an endpoint
in future versions of TRB - meaning that methods like success?
will not be used on the user side. You configure your endpoints with a higher level API. This is the reason that only Operation
has the binary result methods, these concepts don't exist in activity
and dsl
.
Oh BTW, one more thing! An Output
is not a terminus (or "end" as we used to call it). An output defines which outgoing connection goes where, and that might lead to a specific terminus, however, sometimes this might just define what will be the next step, so be careful not to confuse those two concepts.
I will soon explain more about the Wiring API in a Trailblazer Tales episode. :beers:
Hey @elShiaLabeouf feel free to hit me up directly on https://trailblazer.zulipchat.com to discuss :point_up:
Oh, I see.
I've come up with this minimalistic PR. Please take a look.
I didn't realize the outputs were accessible from the operation class itself.
That was quite a bit of overengineering before 😂
Any update on this? I think it would be nice to check easier for different end semantics. Maybe just a one new method?
operation = Payment::Operation::Create.(provider: "bla-unknown")
if operation.success?
render "success"
elsif operation.semantic == :provider_invalid # or operation.semantic?(:provider_invalid)
render "provider_error"
else
render "error"
end
We're putting this into the endpoint
gem - I am working on it as I type, actually! Will update you in the next days! :green_heart:
@eliten00b @elShiaLabeouf Here's a rough outlook of how I envision the interface: https://github.com/trailblazer/trailblazer-endpoint/blob/master/test/matcher_test.rb#L17 - it will look slightly less clumsy in a controller. Any comments here? :beers:
Does this mean any custom terminus is not consider a failure anymore?
@eliten00b Interesting! A custom output has never been a "failure" per definition, that's why we gave it an attribute "semantic". It's up to the user to decide what "not_found" means. What makes you think that this is now different with the above example?
True, I never read that a custom terminus is consider a failure.
Most of our operation use the run Operation do; end
in rails controllers. When we now started with custom terminus it skips the block. Which is ok, as it is not the ideal success
or pass_fast
semantic.
When I check Operation.().failure?
it is true
if the terminus is a custom one.
From your code it reads that at least the DSL#failure
does not check the same as the Operation#failure?
method. Which does sound ok to me, if the check become more fine.
From the initial code:
op = Execute.call({ params: { provider: :paypal } })
op.paypal? # => true
op.success? # => false
op.failure? # => false
currently it would be:
op = Execute.call({ params: { provider: :paypal } })
# => <Trailblazer::Operation::Railway::Result:false>
op.event.to_h[:semantic] == :paypal # => true
op.success? # => false
op.failure? # => true
@eliten00b Good point! Let me finalize my code over here and then we can discuss the API for endpoint
. :coffee:
Hello @apotonick and the Trailblazer team!
I think Adding outputs is a really powerful feature since it enables handling multiple outcomes during the operation run.
I also enjoy using
operation.success?
andoperation.failure?
methods that come in handy in controller actions routing.But when I'm using a custom output in an operation, to check which pipeline the operation went, I have to do the following:
I think it would be more intuitive and kinda elegant if instead of
operation.event.to_h[:semantic] == :provider_invalid
I could use a binary state methodoperation.provider_invalid?
I'd like to come up with a proposal to add such methods to a number of classes/objects like
#<Trailblazer::Activity::Railway::End::Success semantic=:success>
,#<Trailblazer::Activity::End semantic=:paypal>
etc..I have tested my changes locally and it works like this:
The changes
To achieve this I had to add bits of code to three gems:
First, I added
success?
failure?
fail_fast?
pass_fast?
and<custom_output>?
toTrailblazer::Activity::End
:success?
,failure?
and addedmethod_missing
for delegation inTrailblazer::Operation::Result
:class Trailblazer::Operation class Result def initialize(event, data) @event, @data = event, data end