106
Large scale Rails applications Florian Dutey

RubyConf Taiwan 2016 - Large scale Rails applications

Embed Size (px)

Citation preview

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!

ApplicationHttp

RequestResponse

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

• Domain Specific Language

Modularity

• Controller

• Test

• Rake tasks

• Jobs

• Daemons

• …

Single Responsibility Principle (SRP)

Not SRP

SRP

Useremail

password

first_name

last_name

address_1

address_2

zip_code

city

country

User

email

password

User::Profileuser_id

first_name

last_name

User::Addressuser_idaddress_1

address_2

zip_code

city

country

Break things downminimalist 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_service_spec

Services Forms Policies

Queries Adapters Models

Application

Forms (1)

Convert inputs in Domain language

Forms (2)

USERemail

password

Forms (3)

Forms (4)

Forms (5)

Forms (6)

User

email

password

User::Profileuser_id

first_name

last_name

Useremail

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)

Useremail

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 integration servers

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 pipeline

• Split FE / BE in different projects

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 Java / React community does

Rails is a fantastic prototyping tool!

Rails is NOT an application framework

Rails is a fantastic web framework!

Thank you!

Q & A