exponentially / extreme_system_example

Example umbrella project that demonstrates how Extreme.System should be used
3 stars 0 forks source link

What is _ok? #2

Closed drozzy closed 6 years ago

drozzy commented 6 years ago

extreme_system is working great so far with exec/handle_exec. Trying to rewrite it as in the example here:

https://github.com/exponentially/extreme_system_example/blob/06b1b1c09a2701b8d29fe124cb9f8c517c5b7919/apps/users/lib/example/aggregates/user.ex

I'm not sure what _ok function does...

https://github.com/exponentially/extreme_system_example/blob/06b1b1c09a2701b8d29fe124cb9f8c517c5b7919/apps/users/lib/example/aggregates/user.ex#L26

It's very confusing in general, sorry...would be nice if there was no impl module - as it seems like it's just doing an extra level of indirection, not sure why...

Like, for example, why does the top level module User validate parameters here, but not impl? What is params_from_the_above and is it different from params?

https://github.com/exponentially/extreme_system_example/blob/06b1b1c09a2701b8d29fe124cb9f8c517c5b7919/apps/users/lib/example/aggregates/user.ex#L22-L30

I have hard time understanding what arguments look like to handle_cmd (when the client calls it). Does the parameter to new here contain the id as the client passed it in, or is it automatically added?

https://github.com/exponentially/extreme_system_example/blob/06b1b1c09a2701b8d29fe124cb9f8c517c5b7919/apps/users/lib/example/aggregates/user.ex#L17

burmajam commented 6 years ago

_ok(from, state) is a shorthand for {:noblock, from, {:ok, state.version}, state} (https://github.com/exponentially/extreme_system/blob/master/lib/system/gen_aggregate.ex#L234)

Impl module is just the way I like to separate logic for command validation and event generation from state validation that I leave in aggregate module. You can put all in aggregate module but I find it more readable to look at handle_cmd in aggregate module and see what is allowed in what state. In this example I see that if name from command params is the same as the name in state no events should be generated but result of command is ok (idempotent message). If name is not the same that we should proceed with command validation and event generation and that is done in Impl module. That's easier to test as well.

params_from_the_above are the same params from handle_cmd (second argument). I just proxy them to anonymous function so you can pattern match params with current aggregate state like in this example with names.

params in handle_cmd are most likely params from your phoenix controller action. It really depends how you invoke command.

When it comes to id in :new command it has to be present here, but layer above (MessageHandler in our example) will try to find "id" in params. If it is not present it will generate one for you.

burmajam commented 6 years ago

Extreme.System is product that was born as code extraction from few CQRS+ES systems I've been working on. It is very opinionated as any other framework is but not documented at all since I didn't have ambitions to promote it. That being said, I understand that things look odd for you but please don't hesitate to ask, I'll try to explain how and why things work the way they do. Also try this example and follow API request through all layers and things will be more clear for you once you get familiar with code flow.

drozzy commented 6 years ago

Hey, I figured it out in the end. Once you understand what goes where, it works! Some docs would be really nice and maybe I’ll contribute some later.

burmajam commented 6 years ago

I do agree that documentation is missing so any PR will be appreciated :)