[Practical] Functional Programming in Rails

53
FUNCTIONAL PROGRAMMING Practical! RAILS RUBY IN ON BY

description

Tired of writing messy messy "if" statements for all your exception handling? Learn how to take full advantage of functional programming theory, without the theory, Ruby-style! https://github.com/mindeavor/solid_use_case

Transcript of [Practical] Functional Programming in Rails

Page 1: [Practical] Functional Programming in Rails

FUNCTIONALPROGRAMMINGPr

actical!

RAILSRUBYIN

ON

BY

Page 2: [Practical] Functional Programming in Rails

Overview

• What is a Service Layer? • Railway Oriented Programming • Creating Beautifully Composable Services

Page 3: [Practical] Functional Programming in Rails

What is a

LAYER?

SERVICE

Page 4: [Practical] Functional Programming in Rails

What is a

LAYER

SERVICE??

Page 5: [Practical] Functional Programming in Rails

A Service is an object that represents a process.

Page 6: [Practical] Functional Programming in Rails

A process is something you do.

• Typically initiated by the user • Usually implemented as a dedicated class • Named with verbs, not nouns • Examples: SignupUser, PurchaseItem, etc.

SERVICES

Page 7: [Practical] Functional Programming in Rails

SignupUser

Purchase Item

RAILS

SERVICES

SERVICE LAYER

Payout Account

Page 8: [Practical] Functional Programming in Rails

A Service in Rails

SERVICES

CODE EXAMPLE

A ServiceUsage in Controller

Page 9: [Practical] Functional Programming in Rails

[Naive] ValidationsCODE EXAMPLE

A Service

Usage in Controller

SERVICES

Page 10: [Practical] Functional Programming in Rails

Why a Service useful?

• It encapsulates domain logic • It thins out your models & controllers • It ties together cross-cutting concerns • It makes your Rails app easier to test.

SERVICES

Page 11: [Practical] Functional Programming in Rails

A service layer is about clear separation.

• Rails depends on the service layer • The service layer knows nothing about Rails (routes, controllers, & views)

• Other things could depend on the service layer (REST API, web sockets, rake tasks, etc.)

• ActiveRecord is unavoidable, however.SERVICES

Page 12: [Practical] Functional Programming in Rails

SERVICES

Page 13: [Practical] Functional Programming in Rails

Quick Recap

• A service is an object that represents a process • Services encapsulate domain logic for specific

processes • No functional programming (yet).

SERVICES

Page 14: [Practical] Functional Programming in Rails

RAILWAY ORIENTED

PROGRAMMING

http://fsharpforfunandprofit.com/posts/recipe-part2/

Page 15: [Practical] Functional Programming in Rails

Services: Another Perspective

A service is a sequence of steps • They often involve a lot of setup • Authentication, authorization, validation, etc.

Any one of these steps could fail • How to handle failure??

RAILWAY

Page 16: [Practical] Functional Programming in Rails

Naive ValidationsCODE EXAMPLE (REVISITED)

A Service RAILWAY

Page 17: [Practical] Functional Programming in Rails

Can we do be!er?

RAILWAY

What if each step was an independent method?

How would each step communicate?

Page 18: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming RAILWAY

The “Switch”

Input → Success!

Failure.

fetch_item

DIAGRAM

Page 19: [Practical] Functional Programming in Rails

RAILWAY

The “Switch”

Input → Success!

Failure

fetch_item

CODE EXAMPLE

Page 20: [Practical] Functional Programming in Rails

RAILWAY

The “Switch”

Input → Success!

Failure.

fetch_item

CODE EXAMPLE

Failure.Success!

Page 21: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming RAILWAY

Our Target Flow

on successSuccess!

Failure.

Input →

fetch_item validate

on failure

Page 22: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming RAILWAY

Our Target Flow

Success!Failure.

Input →create_ordervalidatefetch_item

Page 23: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming RAILWAY

Our Target Flow

Success!Failure.

Input →create_ordervalidatefetch_item

IT’D BE COOL IF WE COULD CONNECT THESE TOGETHER

Page 24: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming RAILWAY

Connecting Switches

Success!Failure.

Input →create_ordervalidatefetch_item

create_ordervalidatefetch_item

Page 25: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming RAILWAY

Connecting Switches

Success!Failure.

Input →create_ordervalidatefetch_item

create_ordervalidatefetch_item

create_ordervalidatefetch_item

Success!Failure.

Page 26: [Practical] Functional Programming in Rails

RAILWAY

Connecting SwitchesCODE EXAMPLES

create_ordervalidatefetch_item

?? ??

Page 27: [Practical] Functional Programming in Rails

RAILWAY

Connecting SwitchesCODE EXAMPLES

create_ordervalidatefetch_item

?? ??

HOW DO WE CONNECTIT ALL TOGETHER?

? ????

??

?

Page 28: [Practical] Functional Programming in Rails

RAILWAY

Answer:

Page 29: [Practical] Functional Programming in Rails

RAILWAY

¯\_(ツ)_/¯ Answer:

Page 30: [Practical] Functional Programming in Rails

RAILWAY

¯\_(ツ)_/¯ Answer:

IT DOESN’T MATTER!

Page 31: [Practical] Functional Programming in Rails

RAILWAY

¯\_(ツ)_/¯ Answer:

IT DOESN’T MATTER! :D

Page 32: [Practical] Functional Programming in Rails

RAILWAY

¯\_(ツ)_/¯ Answer:

IT DOESN’T MATTER! :D

(actual answer: monads)

Page 33: [Practical] Functional Programming in Rails

There’s a gem for that!Doesn’t matter.

RAILWAY

github.com/mindeavor/solid_use_case

Page 34: [Practical] Functional Programming in Rails

There’s a gem for that!Don’t worry.

Page 35: [Practical] Functional Programming in Rails

Handling failures?

RAILWAY

What about

github.com/mindeavor/solid_use_case

Page 36: [Practical] Functional Programming in Rails
Page 37: [Practical] Functional Programming in Rails

Quick Recap

• Split steps into methods • Return a success or failure in each one • Elegant (with gem) error handling! • Steps can be tested independently

RAILWAY

Page 38: [Practical] Functional Programming in Rails

COMPOSING SERVICES

FOR MAXIMUM COOLNESS

Page 39: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming COMPOSE

Remember This?

Success!Failure

Input →create_ordervalidatefetch_item

create_ordervalidatefetch_item

create_ordervalidatefetch_item

Success!Failure

Page 40: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming COMPOSE

Input → Success!Failure

create_ordervalidatefetch_item

What if we treat it like a single thing…

Page 41: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming COMPOSE

Input → Success!FailurePurchaseItem

What if we treat it like a single thing…

Page 42: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming COMPOSE

Input → PurchaseItem Success!Failure

What if we treat it like a single thing…

Page 43: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming COMPOSE

…and then connect it to other things??

Input →PurchaseItem

Success!

Failure

Page 44: [Practical] Functional Programming in Rails

Source: http://www.slideshare.net/ScottWlaschin/railway-oriented-programming COMPOSE

Input →PurchaseItem EmailReceipt

Success!

Failure

…and then connect it to other things??

Page 45: [Practical] Functional Programming in Rails

Service CompositionCODE EXAMPLE

COMPOSE

Page 46: [Practical] Functional Programming in Rails

Service CompositionCODE EXAMPLE

Another Service!

COMPOSE

Page 47: [Practical] Functional Programming in Rails

Service CompositionCODE EXAMPLE

Another Service!

COMPOSE

Page 48: [Practical] Functional Programming in Rails

Recap

• We can compose services like we can steps (in fact we can compose anything that returns our success or failure)

• Functional programming rocks!

COMPOSE

Page 49: [Practical] Functional Programming in Rails

Conclusion

• Service layers are great for apps more complex than CRUD

• Railway oriented programming is great for seamless error handling

• Functional programming gives us composable services!

Page 50: [Practical] Functional Programming in Rails

In the end, don’t take my word for it.

Page 51: [Practical] Functional Programming in Rails

TRY IT YOURSELF!

Page 52: [Practical] Functional Programming in Rails

Thanks!Hurrah!

END.THE

BY

- Gilbert (@mindeavor)

Page 53: [Practical] Functional Programming in Rails

Further Reading

• http://martinfowler.com/eaaCatalog/serviceLayer.html • https://gist.github.com/blaix/5764401 • http://fsharpforfunandprofit.com/posts/recipe-part2/ • The gem: https://github.com/mindeavor/solid_use_case