[practical] functional programming in rails

Post on 27-Aug-2014

128 Views

Category:

Software

3 Downloads

Preview:

Click to see full reader

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

FUNCTIONALPROGRAMMINGPr

actical!

RAILSRUBYIN

ON

BY

Overview

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

What is a

LAYER?

SERVICE

What is a

LAYER

SERVICE??

A Service is an object that represents a process.

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

SignupUser

Purchase Item

RAILS

SERVICES

SERVICE LAYER

Payout Account

A Service in Rails

SERVICES

CODE EXAMPLE

A ServiceUsage in Controller

[Naive] ValidationsCODE EXAMPLE

A Service

Usage in Controller

SERVICES

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

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

SERVICES

Quick Recap

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

processes • No functional programming (yet).

SERVICES

RAILWAY ORIENTED

PROGRAMMING

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

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

Naive ValidationsCODE EXAMPLE (REVISITED)

A Service RAILWAY

Can we do be!er?

RAILWAY

What if each step was an independent method?

How would each step communicate?

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

The “Switch”

Input → Success!

Failure.

fetch_item

DIAGRAM

RAILWAY

The “Switch”

Input → Success!

Failure

fetch_item

CODE EXAMPLE

RAILWAY

The “Switch”

Input → Success!

Failure.

fetch_item

CODE EXAMPLE

Failure.Success!

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

Our Target Flow

on successSuccess!

Failure.

Input →

fetch_item validate

on failure

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

Our Target Flow

Success!Failure.

Input →create_ordervalidatefetch_item

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

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

Connecting Switches

Success!Failure.

Input →create_ordervalidatefetch_item

create_ordervalidatefetch_item

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.

RAILWAY

Connecting SwitchesCODE EXAMPLES

create_ordervalidatefetch_item

?? ??

RAILWAY

Connecting SwitchesCODE EXAMPLES

create_ordervalidatefetch_item

?? ??

HOW DO WE CONNECTIT ALL TOGETHER?

? ????

??

?

RAILWAY

Answer:

RAILWAY

¯\_(ツ)_/¯ Answer:

RAILWAY

¯\_(ツ)_/¯ Answer:

IT DOESN’T MATTER!

RAILWAY

¯\_(ツ)_/¯ Answer:

IT DOESN’T MATTER! :D

RAILWAY

¯\_(ツ)_/¯ Answer:

IT DOESN’T MATTER! :D

(actual answer: monads)

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

RAILWAY

github.com/mindeavor/solid_use_case

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

Handling failures?

RAILWAY

What about

github.com/mindeavor/solid_use_case

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

COMPOSING SERVICES

FOR MAXIMUM COOLNESS

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

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…

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

Input → Success!FailurePurchaseItem

What if we treat it like a single thing…

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

Input → PurchaseItem Success!Failure

What if we treat it like a single thing…

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

…and then connect it to other things??

Input →PurchaseItem

Success!

Failure

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

Input →PurchaseItem EmailReceipt

Success!

Failure

…and then connect it to other things??

Service CompositionCODE EXAMPLE

COMPOSE

Service CompositionCODE EXAMPLE

Another Service!

COMPOSE

Service CompositionCODE EXAMPLE

Another Service!

COMPOSE

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

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!

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

TRY IT YOURSELF!

Thanks!Hurrah!

END.THE

BY

- Gilbert (@mindeavor)

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

top related