SlideShare uma empresa Scribd logo
1 de 45
This page was intentionally left blank.
or... rethinking Rails architecture
...if there's any.
Rails new way
A few facts about me
Blogger
kamil.lelonek.me
Live in
Wrocław,
Poland
CTO at
woumedia,
Denmark
Full-stack Developer
(mostly Ruby, Scala)
@KamilLelonek
DCI
DDD
CQRS
Event Sourcing
Actor model
Reactive programming
Microservices
Service objects
What won't be about?
No fancy
stuff
What will be about then?
Why?
evel, everything in Rails is crying for separation
For every Rails project, there are exactly two outcomes.
Either they can be well
designed.
or you will struggle a lot when
maintaining them.
Because there is no architecture.
So why a conventional Rails architecture fails?
Why to rails-way at all in that case?
When not to rails way?
Where's the problem?
simplicity vs maintainability
models with thousands of lines of code
following the Rails conventions
What are we doing?
What is the solution?
MVC
?
So, why do we need Rails?
Rails needs more abstraction layers.
time to refactor
It's
Value Objects
immutable no identity
Entities
differs by ID stateful
Mappers
ActiveRecord -> Domain Object
Renaming,
Coercing, ...
Form Objects
Validation User input -> Domain Object
Repositories
DAO Infrastructural layer
Queries
Wraps query logic Query API
Validators
Ensure valid models Ensure valid data
Use cases
Slim down controllers Data flow orchestration
Testing
Features
No more "where do I put this kind of logic?"
Clean architecture and right order
A lot of boilerplate
Not very useful for simple domain
Infrastructure
Resources
https://github.com/KamilLelonek/rails-new-way/
https://github.com/KamilLelonek/react-new-way/
http://bit.ly/controversial-service-objects
http://bit.ly/ddd-dictionary
http://bit.ly/decouple-from-activerecord
Q&A
Thank you for having me here
rails new app --skip-rails

Mais conteúdo relacionado

Semelhante a Rails New Way

It's OK to make a new folder within Rails.
It's OK to make a new folder within Rails.It's OK to make a new folder within Rails.
It's OK to make a new folder within Rails.
cschaafsma
 
Intro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate JavascriptIntro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate Javascript
Andrew Lovett-Barron
 
Server-side Web development via Ruby on Rails
Server-side Web development via Ruby on RailsServer-side Web development via Ruby on Rails
Server-side Web development via Ruby on Rails
g3ppy
 

Semelhante a Rails New Way (20)

Ruby on rails
Ruby on railsRuby on rails
Ruby on rails
 
If NoSQL is your answer, you are probably asking the wrong question.
If NoSQL is your answer, you are probably asking the wrong question.If NoSQL is your answer, you are probably asking the wrong question.
If NoSQL is your answer, you are probably asking the wrong question.
 
The CQRS diet
The CQRS dietThe CQRS diet
The CQRS diet
 
AWS case study: real estate portal
AWS case study: real estate portalAWS case study: real estate portal
AWS case study: real estate portal
 
Moving from Relational to Document Store
Moving from Relational to Document StoreMoving from Relational to Document Store
Moving from Relational to Document Store
 
Domain oriented development
Domain oriented developmentDomain oriented development
Domain oriented development
 
On nosql
On nosqlOn nosql
On nosql
 
NoSQL
NoSQLNoSQL
NoSQL
 
Ruby On Rails Overview
Ruby On Rails OverviewRuby On Rails Overview
Ruby On Rails Overview
 
Ruby Metaprogramming 08
Ruby Metaprogramming 08Ruby Metaprogramming 08
Ruby Metaprogramming 08
 
A Tour of Ruby On Rails
A Tour of Ruby On RailsA Tour of Ruby On Rails
A Tour of Ruby On Rails
 
NoSql Databases
NoSql DatabasesNoSql Databases
NoSql Databases
 
It's OK to make a new folder within Rails.
It's OK to make a new folder within Rails.It's OK to make a new folder within Rails.
It's OK to make a new folder within Rails.
 
No Sql
No SqlNo Sql
No Sql
 
Intro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate JavascriptIntro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate Javascript
 
Server-side Web development via Ruby on Rails
Server-side Web development via Ruby on RailsServer-side Web development via Ruby on Rails
Server-side Web development via Ruby on Rails
 
CQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architectureCQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architecture
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
 
Beyond rails new
Beyond rails newBeyond rails new
Beyond rails new
 
Minnebar 2013 - Scaling with Cassandra
Minnebar 2013 - Scaling with CassandraMinnebar 2013 - Scaling with Cassandra
Minnebar 2013 - Scaling with Cassandra
 

Mais de Kamil Lelonek (8)

Angular2 ecosystem
Angular2 ecosystemAngular2 ecosystem
Angular2 ecosystem
 
Elixir metaprogramming
Elixir metaprogrammingElixir metaprogramming
Elixir metaprogramming
 
Introduction to Web Security
Introduction to Web SecurityIntroduction to Web Security
Introduction to Web Security
 
Crystal
CrystalCrystal
Crystal
 
Ansible
AnsibleAnsible
Ansible
 
Scala vs ruby
Scala vs rubyScala vs ruby
Scala vs ruby
 
A brief intro to RubyMotion
A brief intro to RubyMotionA brief intro to RubyMotion
A brief intro to RubyMotion
 
oAuth wroclove
oAuth wrocloveoAuth wroclove
oAuth wroclove
 

Último

The basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptxThe basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptx
heathfieldcps1
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdf
QucHHunhnh
 
Beyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactBeyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global Impact
PECB
 
Seal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptxSeal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptx
negromaestrong
 

Último (20)

PROCESS RECORDING FORMAT.docx
PROCESS      RECORDING        FORMAT.docxPROCESS      RECORDING        FORMAT.docx
PROCESS RECORDING FORMAT.docx
 
Energy Resources. ( B. Pharmacy, 1st Year, Sem-II) Natural Resources
Energy Resources. ( B. Pharmacy, 1st Year, Sem-II) Natural ResourcesEnergy Resources. ( B. Pharmacy, 1st Year, Sem-II) Natural Resources
Energy Resources. ( B. Pharmacy, 1st Year, Sem-II) Natural Resources
 
psychiatric nursing HISTORY COLLECTION .docx
psychiatric  nursing HISTORY  COLLECTION  .docxpsychiatric  nursing HISTORY  COLLECTION  .docx
psychiatric nursing HISTORY COLLECTION .docx
 
The basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptxThe basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptx
 
Grant Readiness 101 TechSoup and Remy Consulting
Grant Readiness 101 TechSoup and Remy ConsultingGrant Readiness 101 TechSoup and Remy Consulting
Grant Readiness 101 TechSoup and Remy Consulting
 
1029 - Danh muc Sach Giao Khoa 10 . pdf
1029 -  Danh muc Sach Giao Khoa 10 . pdf1029 -  Danh muc Sach Giao Khoa 10 . pdf
1029 - Danh muc Sach Giao Khoa 10 . pdf
 
Beyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactBeyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global Impact
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdf
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot Graph
 
Mixin Classes in Odoo 17 How to Extend Models Using Mixin Classes
Mixin Classes in Odoo 17  How to Extend Models Using Mixin ClassesMixin Classes in Odoo 17  How to Extend Models Using Mixin Classes
Mixin Classes in Odoo 17 How to Extend Models Using Mixin Classes
 
Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...
Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...
Ecological Succession. ( ECOSYSTEM, B. Pharmacy, 1st Year, Sem-II, Environmen...
 
Unit-V; Pricing (Pharma Marketing Management).pptx
Unit-V; Pricing (Pharma Marketing Management).pptxUnit-V; Pricing (Pharma Marketing Management).pptx
Unit-V; Pricing (Pharma Marketing Management).pptx
 
Class 11th Physics NEET formula sheet pdf
Class 11th Physics NEET formula sheet pdfClass 11th Physics NEET formula sheet pdf
Class 11th Physics NEET formula sheet pdf
 
Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptx
 
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptxINDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
 
Sociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning ExhibitSociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning Exhibit
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17
 
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxBasic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17
 
Seal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptxSeal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptx
 

Rails New Way

Notas do Editor

  1. Hello guys, in this presentation we're gonna rethink Rails architecture together, discuss some pitfalls > and propose some solutions for a better development process.
  2. At the very beginning I'd like to clarify what we won't talk about directly. > It won't be about ... > and some other fancy stuff. But still you don't know what to expect, right?
  3. So, I can ensure that I will mention about Value Objects, Entities, Queries and Repositories. > I'll try to present and describe a lot of useful building blocks for modern applications.
  4. What is the reason for rearranging something that is already done? Well, when it's done poorly, it's worth to review it, because ... But those cries go unheard, mostly.
  5. Nowadays, Rails applications can end up in two ways: > Either someone in the team is an experienced architect and leads the software to an advanced design with service layer, view components, maybe forms, and so on. > or a classy way, when a project strictly follows the Rails Way and will end up as a code disaster.
  6. I would like to apologise to anyone I have offended. And to those I haven't offended yet. Please be patient. I will get to you shortly.
  7. Based on what I said you may wonder now when to follow the Rails way without introducing any additional architecture. There are some cases when that may be useful. > It's easy to learn and add new features, you can simply add new concepts by running scaffolding. > For fast production-ready or production-convertible prototypes that you need to present to your potential customer as a proof of concept. > It allows you to simple jump between different projects without diving into a custom architecture > Perfect for CRUD applications of course.
  8. However, usually you build bigger apps. You have a way more complex problems and provide not so simple solutions. There's when an additional architecture comes handy. > When you maintain long-term projects > In case you have experienced programmers who probably want to try something more > When your domain is big and business logic is complex > When your team is distributed
  9. > Once again, did we fall into some kind of trap? What price do we pay for Rails’ simplicity in trade for maintainability? Were we tempted by this simplicity without thinking about the maintenance? > Is it worth writing models with thousands of lines of code and building a throw-away software kludge that is impossible to maintain, just for the sake of development speed? > How fast are we on the very beginning compared to the future development? Is it worth blindly hacking away and following the Rails conventions without thinking about whether this is the right place for that code?
  10. Here is how the majority of applications are created these days. We just do rails new and that's it.
  11. And here is how it actually should be done. rails-api is an awesome gem that let you build applications which expose RESTful endpoints with JSON data for separated frontend apps.
  12. Rails downright encourages us to write big, monolithic applications in an MVC manner instead of splitting them into separate layers or a hexagonal architecture. Right now, instead of identifying and implementing new layers like form objects, things get violently pressed into the controller or alternatively the model, both in the framework itself and in your application code. All that just because of fearing over-abstraction. > Why on earth is Rails constantly trying to solve incredible complex problems in one gigantic, monolithic class?
  13. ... Should we drop Rails at all? After all we have great frameworks such are > Lotus > Volt > or rom-rb? BTW, anyone use either of them?
  14. We can still use Rails, but ...
  15. The first building block to refactor our applications is a Value Object. > Value object  is  an immutable object that describes some characteristic or attribute > but carries no concept of identity.
  16. This is an example of Value Object. I'm using Virtus gem from a friend of mine which provides nice helpers for value objects. We can specify attributes and their types.
  17. Entity  is  an object fundamentally defined not by its attributes. > It differs by ID, which have to be unique within an aggregate, not necessary globally. Never share an entity between aggregates. > A unique thing that has a life cycle and can change state. Sometimes in one context something is an entity while in another it is just a value object. (Aggregate — a cluster of domain objects that can be treated as a single unit to provide a specific functionality and for the purpose of data changes) Can you find some examples of that?
  18. Once again using Virtus, we can easily create Entity with given attributes and their types.
  19. Taking data from one representation and converting it into another is done by using mappers. > Mapper is an object that takes a record and turns it into a domain object. You can design your domain objects exactly the way you want and configure mappings accordingly. By defining a mapper you are specifying which entity class is going to be instantiated and what attributes are going to be used. > Mapping is an extremely powerful concept. It can: Rename attributes Coerce values Build aggregate objects Build immutable value objects ...
  20. This is a mapper that takes a record from a DB and turns is into a domain object with particular attributes.
  21. Submitting form data is a common feature of web applications – allowing users to submit their information > and giving them feedback whether the information is valid or not. And for that purpose we use form objects. > Form Object is an object that wraps incoming input from a user and provides a validation to ensure that only correct data is processed within an application anytime later.
  22. And this is an example where I'm using Reform gem from my another friend @apotonick and this gem is used to wrap user's input, validate it, and map it into a particular entity. So from given params we get completely valid domain object.
  23. > Repository — mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects. > A repository implementation is also an example of an infrastructural service. Therefore the specifics of the communication with durable storage mechanisms are handled in the infrastructure layer.
  24. Our repository uses Dependency Injection to accept a particular adapter, which can be ActiveRecord during development and production or InMemoryAdapter while we are testing our code. Later on we use injected adapter to create and store a particular object from our form object.
  25. Database queries, even simple ones, can be both repetitive and hard to read and comprehend. With more complex queries, especially ones that embed data from multiple collections or tables, this process can get messy to write and even messier to maintain. > Query object - provides a nice tool for extracting query logic and associated operations into a contained module, pulling the logic out into a more maintainable and readable structure, > while also providing a very readable API where the query object is used.
  26. In this query we are finding a record by it's id and then we map it onto our domain entity object. In case of failure we raise not found error.
  27. > Validators - are used to ensure that only valid models exist within your application > and therefore only valid data is saved into your database. It may be important for your application to ensure that every user provides a valid email address and a phone number in a correct format. There are several ways to validate data before it is saved into your database, including native database constraints, client-side validations, controller-level validations, but validators wrap all of them in a one place together.
  28. This is an example of a validator that just checks if given params conform our form object constraints. There's no DB checking and other kind of validations.
  29. > Use case - a component that is responsible for the coordination logic we tend to put into our controllers. And being a coordinator, a use case should not do any computation or state management. There is no one-to-one mapping between use cases and controllers. One controller can support multiple different use cases and vice versa. > These use cases orchestrate the flow of data to, and from the entities, and direct those entities to use their enterprise wide business rules to achieve the goals of the use case.
  30. In this example I use solid-use-case gem which helps define steps for a specific flow. So when making an order we can validate incoming params, sore the result and dump read model into our database.
  31. How fast are your tests? Do they rely on a database? How easily can you switch from relational schema to NoSQL documents or even YAML store? Do you have fat Models that leak up to Controllers or even Views? Does your application depend on details of a particular ORM implementation?
  32. Using previously described building blocks we can easily avoid aforementioned problems. We define in-memory adapter that behaves similarly to active record and can be injected into our repositories.
  33. Here you can see an example usage of it. We are creating an in-memory adapter and inject it in our repository that we are using later. In more complex cases we can define an in-memory repository instead of just an adapter.
  34. And that's all of the building blocks for now. I didn't mentioned about Service Objects, but it's a topic for yet another talk. > What are the possible disadvantages of them? ... > And what about benefits?
  35. With a new architecture comes a new infrastructure as well.
  36. In this picture I'm showing you an overall flow within the recent startup I've been doing. I will focus on particular parts right now.
  37. Firstly, I've extracted a front-end part completely. I don't have views served by a rails application. Instead, I have a couple of lightweight front-end static single page applications build, compiled and minified using Brunch or Middleman with all goodness from CDN servers. They are using REST API to connect with backend application.
  38. The backend is divided as well. I'm using one core rails-api server, which connects to 3 different micro services using CQS flow, vertx queuing system and their own separated databases. Each microservice describes one bounded context and wraps a specific responsibilities that are called from the core server.
  39. Besides the benefits I'be told you already there is also a note about deployment. I can independently deploy either front-end application or even a micro-service. Using pipelines and integration server I can easily extend only some part of my application which is extremely fast and efficient.
  40. Here are some resources I'd like to share with you. I've written a couple of blogposts related to the presented topic. Moreover, I created a sample application to show you working examples with discussed building blocks.
  41. Well, that's it for now. Have you guys any questions for me?