Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Large scale Rails
applications
Florian Dutey
www.strikingly.com
We hire!
2007
1.2.3
Fat Models
Skinny Controllers
If it’s not a controller job,
leave it to the model.
If the screwdriver can’t solve it,
use the hammer.
Business complexity
Technical complexity
Solution = Complexity²
Rails doesn't scale!
NOT Rails!
Application
Http
Request
Response
Request Router Controller
ResponseView
Models
Request Router Controller
ResponseView
Models
Application
Principles
• Modularity
• Single Responsibility Object
• Plain Old Ruby Objects
• Inversion Of Control
• Stateless Objects...
Modularity
• Controller
• Test
• Rake tasks
• Jobs
• Daemons
• …
Single Responsibility Principle
(SRP)
Not SRP
SRP
User
email
password
first_name
last_name
address_1
address_2
zip_code
city
country
User
email
password
User::Profile
user_id
first_name
last_name
User::Address
user_id
address_1
address_2
zip_code
city
cou...
Break things down
minimalist objects
“Make everything as simple as possible,
but not simpler.”
Albert Einstein
Plain Old Ruby Objects (PORO)
PORO
Not PORO
Inversion of controls
Separate what
and when
Why?
• Separate responsibilities
• Remove strong dependencies
• Easier to test
• Write highly abstract processes
Stateless objects
Stateless
Statefull
Why?
• No setup
• Predictable
Domain Specific Language
Router Controller
Domain
API language
Domain Specific Language
View API language
Break down
Request Router Controller
ResponseView
Application
?
??
??
Models
Services
Application
Forms Policies
Queries Adapters Models
Services Forms Policies
Queries Adapters Models
Application
Services (1)
Describe processes
Services (2)
Services (3)
Services (4)
Create != Signup
Services (5)
Services (6)
Services (7)
Services (8)
User::SignupService
Payment::SignupService
user/signup_service_spec
Payment::SignupService
payment/signup_ser...
Services Forms Policies
Queries Adapters Models
Application
Forms (1)
Convert inputs in
Domain language
Forms (2)
USER
email
password
Forms (3)
Forms (4)
Forms (5)
Forms (6)
User
email
password
User::Profile
user_id
first_name
last_name
User
email
password
first_name
last_name
Forms (7)
accepts_nested_attributes_for
Forms (8)
Forms (9)
Forms (10)
Services Forms Policies
Queries Adapters Models
Application
Policies (1)
Describe permissions
Policies (2)
Policies (3)
Policies (4)
Services Forms Policies
Queries Adapters Models
Application
Queries (1)
Describe how to access data
Queries (2)
Queries (3)
Services Forms Policies
Queries Adapters Models
Application
Adapters (1)
Translate DSL into another
Adapters (2)
User
email
password
first_name
last_name
Recurly
Adapters (3)
Adapters (4)
It’s about languages
Adapters (5)
3rd party
API language
Client
Http request
Ruby method
Adapters (6)
Client
API Language
Adapter
DSL
Application
Adapters (7)
Adapters (8)
PaymentManager
RecurlyAdapter StripeAdapter
Benefits
• Easy to test (mock client responses)
• New provider => new adapter
• Easy to migrate
• Fake adapters for integr...
Services Forms Policies
Queries Adapters Models
Application
Models (1)
Data
(& persistency)
Models (2)
If it doesn’t fit in models
…
Models (3)
Then it doesn’t fit in models!
Models (4)
Conclusion
It’s not a perfect solution,
just a guide
Pros
• Easier to browse and discover
• More flexible
• Easier to test
• Easier to debug
• Agnostic (from ActiveRecord)
after_commit
Cons
• Harder to design
• More time on code architecture
• Write more code, more tests
• Write integration tests (IOC)
Small apps
Soft transition
• Code convention
• Focus on data and API
• Express everything in DSL
• Write adapters early
• Drop assets...
Big apps
More tips
• If it doesn’t fit anywhere, think twice
• If it still doesn’t fit anywhere, you need a new layer
• Check what ...
Rails
is a fantastic prototyping tool!
Rails
is NOT an application framework
Rails
is a fantastic web framework!
Thank you!
Q & A
RubyConf Taiwan 2016 - Large scale Rails applications
RubyConf Taiwan 2016 - Large scale Rails applications
RubyConf Taiwan 2016 - Large scale Rails applications
RubyConf Taiwan 2016 - Large scale Rails applications
RubyConf Taiwan 2016 - Large scale Rails applications
RubyConf Taiwan 2016 - Large scale Rails applications
RubyConf Taiwan 2016 - Large scale Rails applications
RubyConf Taiwan 2016 - Large scale Rails applications
Upcoming SlideShare
Loading in …5
×

RubyConf Taiwan 2016 - Large scale Rails applications

295 views

Published on

Rails application have this tendency of becoming super messy and hard to maintain very quickly. This talk covers simple principles that you can apply to avoid traps.

Rails is at best a Web framework, maybe a prototyping framework but not an application framework. Stop using it this way

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

RubyConf Taiwan 2016 - Large scale Rails applications

  1. 1. Large scale Rails applications Florian Dutey
  2. 2. www.strikingly.com
  3. 3. We hire!
  4. 4. 2007 1.2.3
  5. 5. Fat Models Skinny Controllers
  6. 6. If it’s not a controller job, leave it to the model.
  7. 7. If the screwdriver can’t solve it, use the hammer.
  8. 8. Business complexity
  9. 9. Technical complexity
  10. 10. Solution = Complexity²
  11. 11. Rails doesn't scale!
  12. 12. NOT Rails!
  13. 13. Application Http Request Response
  14. 14. Request Router Controller ResponseView Models
  15. 15. Request Router Controller ResponseView Models Application
  16. 16. Principles • Modularity • Single Responsibility Object • Plain Old Ruby Objects • Inversion Of Control • Stateless Objects • Domain Specific Language
  17. 17. Modularity
  18. 18. • Controller • Test • Rake tasks • Jobs • Daemons • …
  19. 19. Single Responsibility Principle (SRP)
  20. 20. Not SRP
  21. 21. SRP
  22. 22. User email password first_name last_name address_1 address_2 zip_code city country
  23. 23. User email password User::Profile user_id first_name last_name User::Address user_id address_1 address_2 zip_code city country
  24. 24. Break things down minimalist objects
  25. 25. “Make everything as simple as possible, but not simpler.” Albert Einstein
  26. 26. Plain Old Ruby Objects (PORO)
  27. 27. PORO
  28. 28. Not PORO
  29. 29. Inversion of controls
  30. 30. Separate what and when
  31. 31. Why? • Separate responsibilities • Remove strong dependencies • Easier to test • Write highly abstract processes
  32. 32. Stateless objects
  33. 33. Stateless
  34. 34. Statefull
  35. 35. Why? • No setup • Predictable
  36. 36. Domain Specific Language
  37. 37. Router Controller Domain API language Domain Specific Language View API language
  38. 38. Break down
  39. 39. Request Router Controller ResponseView Application ? ?? ?? Models
  40. 40. Services Application Forms Policies Queries Adapters Models
  41. 41. Services Forms Policies Queries Adapters Models Application
  42. 42. Services (1) Describe processes
  43. 43. Services (2)
  44. 44. Services (3)
  45. 45. Services (4) Create != Signup
  46. 46. Services (5)
  47. 47. Services (6)
  48. 48. Services (7)
  49. 49. Services (8) User::SignupService Payment::SignupService user/signup_service_spec Payment::SignupService payment/signup_service_spec
  50. 50. Services Forms Policies Queries Adapters Models Application
  51. 51. Forms (1) Convert inputs in Domain language
  52. 52. Forms (2) USER email password
  53. 53. Forms (3)
  54. 54. Forms (4)
  55. 55. Forms (5)
  56. 56. Forms (6) User email password User::Profile user_id first_name last_name User email password first_name last_name
  57. 57. Forms (7) accepts_nested_attributes_for
  58. 58. Forms (8)
  59. 59. Forms (9)
  60. 60. Forms (10)
  61. 61. Services Forms Policies Queries Adapters Models Application
  62. 62. Policies (1) Describe permissions
  63. 63. Policies (2)
  64. 64. Policies (3)
  65. 65. Policies (4)
  66. 66. Services Forms Policies Queries Adapters Models Application
  67. 67. Queries (1) Describe how to access data
  68. 68. Queries (2)
  69. 69. Queries (3)
  70. 70. Services Forms Policies Queries Adapters Models Application
  71. 71. Adapters (1) Translate DSL into another
  72. 72. Adapters (2) User email password first_name last_name Recurly
  73. 73. Adapters (3)
  74. 74. Adapters (4) It’s about languages
  75. 75. Adapters (5) 3rd party API language Client Http request Ruby method
  76. 76. Adapters (6) Client API Language Adapter DSL Application
  77. 77. Adapters (7)
  78. 78. Adapters (8) PaymentManager RecurlyAdapter StripeAdapter
  79. 79. Benefits • Easy to test (mock client responses) • New provider => new adapter • Easy to migrate • Fake adapters for integration servers
  80. 80. Services Forms Policies Queries Adapters Models Application
  81. 81. Models (1) Data (& persistency)
  82. 82. Models (2) If it doesn’t fit in models …
  83. 83. Models (3) Then it doesn’t fit in models!
  84. 84. Models (4)
  85. 85. Conclusion
  86. 86. It’s not a perfect solution, just a guide
  87. 87. Pros • Easier to browse and discover • More flexible • Easier to test • Easier to debug • Agnostic (from ActiveRecord)
  88. 88. after_commit
  89. 89. Cons • Harder to design • More time on code architecture • Write more code, more tests • Write integration tests (IOC)
  90. 90. Small apps
  91. 91. Soft transition • Code convention • Focus on data and API • Express everything in DSL • Write adapters early • Drop assets pipeline • Split FE / BE in different projects
  92. 92. Big apps
  93. 93. More tips • If it doesn’t fit anywhere, think twice • If it still doesn’t fit anywhere, you need a new layer • Check what Java / React community does
  94. 94. Rails is a fantastic prototyping tool!
  95. 95. Rails is NOT an application framework
  96. 96. Rails is a fantastic web framework!
  97. 97. Thank you!
  98. 98. Q & A

×