Slide 1

Slide 1 text

Dry::Transaction Paul Sadauskas RubyConf Denver 2021

Slide 2

Slide 2 text

Hi! Paul Sadauskas Lead Architect at TextUs ● github.com/paul ● @theamazingrando Like everyone else, we’re hiring! https://textus.com/jobs This is the talk that made me want to join TextUs — Jason Taylor Ruby on Rails Podcast Ep 389, Oct 27 2021

Slide 3

Slide 3 text

The Problem Model Controller Where do I put my business logic?

Slide 4

Slide 4 text

Service Objects ● Adapter ● Command ● Decorator ● Query Object ● View Model ● Presenter ● Form Object https://refactoring.guru

Slide 5

Slide 5 text

Command Pattern The Command Pattern creates objects which encapsulate actions and parameters

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Dry-rb

Slide 14

Slide 14 text

Dry::Transaction Dry::Transaction is a business transaction DSL. It provides a simple way to define a complex business transaction that includes processing over many steps and by many different objects. It makes error handling a primary concern by taking a “Railway Oriented Programming” approach to capturing and returning errors from any step in the transaction. ● A business transaction is a series of operations where any can fail and stop the processing. ● A business transaction may resolve its operations using an external container. ● A business transaction can describe its steps on an abstract level without being coupled to any details about how individual operations work. ● A business transaction doesn’t have any state. ● Each operation shouldn’t accumulate state, instead it should receive an input and return an output without causing any side-effects. ● The only interface of an operation is #call(input). ● Each operation provides a meaningful piece of functionality and can be reused. ● Errors in any operation should be easily caught and handled as part of the normal application flow. — From the Dry-Transaction documentation

Slide 15

Slide 15 text

Anatomy of a Transaction ● Each “step” is run in the order declared in the `step` DSL ● Each step returns a “Result”, which is “Success” or “Failure” ● If Success, it gets passed to the next step ● If Failure, execution halts, no more steps are run, and that Failure is returned.

Slide 16

Slide 16 text

Monads Monads are monoids in the category of endofunctors. -- Wikipedia or something

Slide 17

Slide 17 text

Maybe Monad A wrapper than can contain only two possible items: ● Just/Some - wraps the value ● Nothing/None - when the value is missing Monad Presence Absence Haskell/Elm Maybe Just Nothing Rust Option Some None Dry::Monad Maybe Some None

Slide 18

Slide 18 text

Maybe Monad

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

Maybe #bind Some: ● Yields its value to the block ● Block must return a Maybe ● Returns the result of the block None: ● Doesn’t call the block ● Returns self

Slide 23

Slide 23 text

Maybe #fmap Some: ● Similar to bind ● Block doesn’t return a monad ● (fmap wraps block result in one) None: ● Same as bind ● Doesn’t call the block

Slide 24

Slide 24 text

Maybe #value_or Safe way to extract a value or default Some: ● Doesn’t call block ● Returns value None: ● Calls block

Slide 25

Slide 25 text

Maybe helpers

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

Result Monad

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

Step Adapters “Normal” step Step adapters (try and map)

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

Error Handling

Slide 33

Slide 33 text

Error handling

Slide 34

Slide 34 text

Error handling — Matcher DSL

Slide 35

Slide 35 text

Error handling — Matcher DSL

Slide 36

Slide 36 text

Error handling — Matcher DSL

Slide 37

Slide 37 text

Testing

Slide 38

Slide 38 text

Testing — Step Injection

Slide 39

Slide 39 text

Testing — Step injection

Slide 40

Slide 40 text

Custom Step Adapters

Slide 41

Slide 41 text

Custom Step Adapters

Slide 42

Slide 42 text

Custom Step Adapter - Merge

Slide 43

Slide 43 text

Custom Step Adapter - Validate

Slide 44

Slide 44 text

Custom Step Adapter - Other Useful Ones We Wrote

Slide 45

Slide 45 text

Bye! Paul Sadauskas Lead Architect at TextUs ● github.com/paul ● @theamazingrando Like everyone else, we’re hiring! https://textus.com/jobs This is the talk that made me want to join TextUs — Jason Taylor Ruby on Rails Podcast Ep 389, Oct 27 2021