[practical] functional programming in rails
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_caseTRANSCRIPT
![Page 1: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/1.jpg)
FUNCTIONALPROGRAMMINGPr
actical!
RAILSRUBYIN
ON
BY
![Page 2: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/2.jpg)
Overview
• What is a Service Layer? • Railway Oriented Programming • Creating Beautifully Composable Services
![Page 3: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/3.jpg)
What is a
LAYER?
SERVICE
![Page 4: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/4.jpg)
What is a
LAYER
SERVICE??
![Page 5: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/5.jpg)
A Service is an object that represents a process.
![Page 6: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/6.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/7.jpg)
SignupUser
Purchase Item
RAILS
SERVICES
SERVICE LAYER
Payout Account
![Page 8: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/8.jpg)
A Service in Rails
SERVICES
CODE EXAMPLE
A ServiceUsage in Controller
![Page 9: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/9.jpg)
[Naive] ValidationsCODE EXAMPLE
A Service
Usage in Controller
SERVICES
![Page 10: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/10.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/11.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/12.jpg)
SERVICES
![Page 13: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/13.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/14.jpg)
RAILWAY ORIENTED
PROGRAMMING
http://fsharpforfunandprofit.com/posts/recipe-part2/
![Page 15: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/15.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/16.jpg)
Naive ValidationsCODE EXAMPLE (REVISITED)
A Service RAILWAY
![Page 17: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/17.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/18.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/19.jpg)
RAILWAY
The “Switch”
Input → Success!
Failure
fetch_item
CODE EXAMPLE
![Page 20: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/20.jpg)
RAILWAY
The “Switch”
Input → Success!
Failure.
fetch_item
CODE EXAMPLE
Failure.Success!
![Page 21: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/21.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/22.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/23.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/24.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/25.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/26.jpg)
RAILWAY
Connecting SwitchesCODE EXAMPLES
create_ordervalidatefetch_item
?? ??
![Page 27: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/27.jpg)
RAILWAY
Connecting SwitchesCODE EXAMPLES
create_ordervalidatefetch_item
?? ??
HOW DO WE CONNECTIT ALL TOGETHER?
? ????
??
?
![Page 28: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/28.jpg)
RAILWAY
Answer:
![Page 29: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/29.jpg)
RAILWAY
¯\_(ツ)_/¯ Answer:
![Page 30: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/30.jpg)
RAILWAY
¯\_(ツ)_/¯ Answer:
IT DOESN’T MATTER!
![Page 31: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/31.jpg)
RAILWAY
¯\_(ツ)_/¯ Answer:
IT DOESN’T MATTER! :D
![Page 32: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/32.jpg)
RAILWAY
¯\_(ツ)_/¯ Answer:
IT DOESN’T MATTER! :D
(actual answer: monads)
![Page 33: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/33.jpg)
There’s a gem for that!Doesn’t matter.
RAILWAY
github.com/mindeavor/solid_use_case
![Page 34: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/34.jpg)
There’s a gem for that!Don’t worry.
![Page 35: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/35.jpg)
Handling failures?
RAILWAY
What about
github.com/mindeavor/solid_use_case
![Page 36: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/36.jpg)
![Page 37: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/37.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/38.jpg)
COMPOSING SERVICES
FOR MAXIMUM COOLNESS
![Page 39: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/39.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/40.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/41.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/42.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/43.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/44.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/45.jpg)
Service CompositionCODE EXAMPLE
COMPOSE
![Page 46: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/46.jpg)
Service CompositionCODE EXAMPLE
Another Service!
COMPOSE
![Page 47: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/47.jpg)
Service CompositionCODE EXAMPLE
Another Service!
COMPOSE
![Page 48: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/48.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/49.jpg)
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](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/50.jpg)
In the end, don’t take my word for it.
![Page 51: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/51.jpg)
TRY IT YOURSELF!
![Page 52: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/52.jpg)
Thanks!Hurrah!
END.THE
BY
- Gilbert (@mindeavor)
![Page 53: [Practical] Functional Programming in Rails](https://reader036.vdocuments.site/reader036/viewer/2022081717/53fda89c8d7f72a81c8b4a44/html5/thumbnails/53.jpg)
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