SlideShare a Scribd company logo
1 of 32
Download to read offline
@gotar | @oskarszrajer gotar.info
Oskar Szrajer
One year with
on production
What is ROM
(Ruby Object Mapper)
https://github.com/orgs/rom-rb
PERSISTENCE & MAPPING
TOOLKIT FOR RUBY
http://rom-rb.org
Author of ROM
Piotr Solnica | @_solnic_ | http://solnic.eu
author of ROM, Virtus, Dry-*, Rodakase, ...
Community
• dozen of devs
• very active Gitter channel
https://gitter.im/rom-rb/chat
• stable API >1.0v
• battle tested on production
History of ROM
• successor of DataMapper - aka DataMapper v2
• first commit - Feb 1 2012
• first version - v0.1 - Jun 15 2013
• first public version - v0.6 - Mar 22, 2015
• v1.0 - stable API - Jan 6, 2016
Core ideas
• reduced global state to minimum
• immutability
• mix OO with FP
• blazing fast
Core concepts
• Configuration
• Relations
• Commands
• Mappers
Configuration
require 'rom'
config = ROM::Configuration.new(
:sql, 'postgres://localhost/rom_repo'
)
rom = ROM.container(config)
rom.gateways[:default]
# #<ROM::SQL::Gateway:0x007fde7a087158>
ROM::Configuration.new(
default: [:sql, 'postgres://localhost/db'],
legacy: [:sql, 'mysql://localhost/legacy_db'],
marketing: [:yesql, 'postgres://localhost/db', path: './sql'],
cache: [:redis, 'redis://localhost'],
csv: [:csv, File.expand_path('./data.csv', __FILE__],
events: [:event_store, '127.0.0.1:1113']
# ...
)
Relations
class Users < ROM::Relation[:sql]
def by_id(id)
where(id: id)
end
end
rom.relation(:users).by_id(1).to_a
# [{:id=>1, :name=>"Jane"}]
Everything is lazy
(callable)
rom.relation(:users).by_id(1)
#<Db::Relations::Users dataset=#<Sequel::Postgres::Dataset: "SELECT "id", ...
rom.relation(:users).by_id(1).call
# [{:id=>1, :name=>"Jane"}]
rom.relation(:users).by_id(1).only(:id).to_a
# [{:id=>1}]
rom.relation(:users).by_id(1).only(:id).one
# {:id=>1}
Commands
class Create < ROM::Commands::Create[:sql]
relation :users
register_as :create
result :one
end
create_user = rom.command(:users).create
create_user.call(name: 'Jack')
# {id: 2, name: 'Jack'}
class Create < ROM::Commands::Create[:sql]
relation :users
register_as :create
input NewUserParams
validator UserValidator
result :one
end
class AuthorWithBooks < ROM::Commands::Create[:sql]
#...
end
create_authors_with_books = rom.command(:authors) do |authors|
authors.create(:books)
end
create_authors_with_books[authors: evaluated_authors]
# {:id=>1, :code=>"jd001", :name=>"Jane Doe", :email=>"jane@doe.org"}
# {:id=>1, :author_id=>1, :title=>"First", :published_on=>#<Date: 2010-10-10 ((2455480j,
0s,0n),+0s,2299161j)>}
# {:id=>2, :author_id=>1, :title=>"Second", :published_on=>#<Date: 2011-11-11 ((2455877j,
0s,0n),+0s,2299161j)>}
# {:id=>3, :author_id=>1, :title=>"Third", :published_on=>#<Date: 2012-12-12 ((2456274j,
0s,0n),+0s,2299161j)>}
Mappers
class UsersMapper < ROM::Mapper
relation :users
register_as :entity
attribute :id
attribute :name
attribute :age do
rand(18..90)
end
end
users = rom.relation(:users).as(:entity)
users.call
[
{ id: 1, name: "Jane", age: 22 },
{ id: 2, name: "Jack", age: 64 }
]
Pipelines
(everything that responds to #call
can be a mapper)
only_name = -> input { input.map{|u| u[:name]} }
upcase = -> input { input.map{|x| x.upcase} }
users = rom.relation(:users)
result = users >> only_name >> upcase
result.to_a
> ["JANE", "JACK"]
Domain data types &
Repositories
class User < Dry::Types::Value
attribute :name, Types::Strict::String
end
class UserRepo < ROM::Repository
relation :users
def all
users.select(:name).as(User).to_a
end
end
user_repo = UserRepo.new(rom)
user_repo.all
> [#<User name="Jane">, #<User name="Jack">]
My story
My story
Both project use
similar technologies:
• Roda (as HTTP layer)
• ROM
• Yaks (JSON API)
Request cycle
ParamsObject >> Validator >> ROM >>
Mapper(s) >> JSON API Mapper
Mapping &
coercion layer
Mapping &
coercion layer
combine
(or change)
data
convert data to
json api format
CQRS
combining data
class UserRepository < ROM::Repository::Base
relations :users, :tasks
def with_tasks(id)
users.by_id(id).combine_children(many: tasks)
end
end
user_repo.with_tasks.to_a
# [#<ROM::Struct[User] id=1 name="Jane" tasks=[#<ROM::Struct[Task] id=2
user_id=1 title="Jane Task">]>, #<ROM::Struct[User] id=2 name="Jack"
tasks=[#<ROM::Struct[Task] id=1 user_id=2 title="Jack Task">]>]
pros
• separating persistence from application &
encouraging that boundary
• ability to choose appropriate storage (SQL, NoSQL, ...),
but keeping the same API
• possibility to pull from different data sources,
and combine everything together
pros
• easy way to map (manipulate, coerce) data
• freedom
• community
cons
• commands (right now repository do not support them,
force to use very low level API, should be done before v2)
• hard to learn (many new concepts)
• lack of documentation (community will help you)
(currently community works to fix it, and there is always
someone sitting on Gitter to help you)
Worth it?
Q&A
@gotar | @oskarszrajer gotar.info
Thx
@gotar | @oskarszrajer gotar.info

More Related Content

What's hot

What's hot (6)

7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them
 
Mito, a successor of Integral
Mito, a successor of IntegralMito, a successor of Integral
Mito, a successor of Integral
 
PHP Server-side Breakout
PHP Server-side BreakoutPHP Server-side Breakout
PHP Server-side Breakout
 
Linux commd
Linux commdLinux commd
Linux commd
 
Linux commd
Linux commdLinux commd
Linux commd
 
Python Web Interaction
Python Web InteractionPython Web Interaction
Python Web Interaction
 

Viewers also liked

Profile.e (yuki sato)0529
Profile.e (yuki sato)0529Profile.e (yuki sato)0529
Profile.e (yuki sato)0529
Sato Yuki
 
2012 Email Evolution Sneak Peak Webinar: Part 1
2012 Email Evolution Sneak Peak Webinar: Part 12012 Email Evolution Sneak Peak Webinar: Part 1
2012 Email Evolution Sneak Peak Webinar: Part 1
Vivastream
 
(Self) Publishing
(Self) Publishing(Self) Publishing
(Self) Publishing
Vlad Micu
 
Dios es mi Guía
Dios es mi GuíaDios es mi Guía
Dios es mi Guía
adeni11
 

Viewers also liked (20)

Profile.e (yuki sato)0529
Profile.e (yuki sato)0529Profile.e (yuki sato)0529
Profile.e (yuki sato)0529
 
Tarea 1 e busines
Tarea 1 e businesTarea 1 e busines
Tarea 1 e busines
 
2012 Email Evolution Sneak Peak Webinar: Part 1
2012 Email Evolution Sneak Peak Webinar: Part 12012 Email Evolution Sneak Peak Webinar: Part 1
2012 Email Evolution Sneak Peak Webinar: Part 1
 
Status Www Undersøgelse Udenpix
Status Www Undersøgelse UdenpixStatus Www Undersøgelse Udenpix
Status Www Undersøgelse Udenpix
 
fluke presentation voicemail on email – cisco
fluke presentation voicemail on email – ciscofluke presentation voicemail on email – cisco
fluke presentation voicemail on email – cisco
 
Da schau her! Augenfreundliche Gestaltung von e-Learning Kursen
Da schau her! Augenfreundliche Gestaltung von e-Learning KursenDa schau her! Augenfreundliche Gestaltung von e-Learning Kursen
Da schau her! Augenfreundliche Gestaltung von e-Learning Kursen
 
Curso de Alta Formación en Marketing para Empresas de Servicios
Curso de Alta Formación en Marketing para Empresas de ServiciosCurso de Alta Formación en Marketing para Empresas de Servicios
Curso de Alta Formación en Marketing para Empresas de Servicios
 
Servicio Eiden : Opinan nuestros clientes
Servicio Eiden : Opinan nuestros clientesServicio Eiden : Opinan nuestros clientes
Servicio Eiden : Opinan nuestros clientes
 
S&B Parking Operators
S&B Parking OperatorsS&B Parking Operators
S&B Parking Operators
 
Brand boost by wildtangent
Brand boost by wildtangentBrand boost by wildtangent
Brand boost by wildtangent
 
(Self) Publishing
(Self) Publishing(Self) Publishing
(Self) Publishing
 
Examen trimestra diego reyes
Examen trimestra  diego reyesExamen trimestra  diego reyes
Examen trimestra diego reyes
 
Update on the ELIXIR UK node by Chris Ponting
Update on the ELIXIR UK node by Chris PontingUpdate on the ELIXIR UK node by Chris Ponting
Update on the ELIXIR UK node by Chris Ponting
 
CompuSystems Dashboards
CompuSystems DashboardsCompuSystems Dashboards
CompuSystems Dashboards
 
Parroquia de San Pedro y San Pablo (Cabanillas del Campo)
Parroquia de San Pedro y San Pablo (Cabanillas del Campo)Parroquia de San Pedro y San Pablo (Cabanillas del Campo)
Parroquia de San Pedro y San Pablo (Cabanillas del Campo)
 
Estudio earcas
Estudio earcasEstudio earcas
Estudio earcas
 
Droidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offlineDroidcon ES '16 - How to fail going offline
Droidcon ES '16 - How to fail going offline
 
Dios es mi Guía
Dios es mi GuíaDios es mi Guía
Dios es mi Guía
 
Catálogo cement design 2014 low size
Catálogo cement design 2014 low sizeCatálogo cement design 2014 low size
Catálogo cement design 2014 low size
 
Ejercicio de dinamica
Ejercicio de dinamicaEjercicio de dinamica
Ejercicio de dinamica
 

Similar to 1 year with ROM on production

Node js quick tour v2
Node js quick tour v2Node js quick tour v2
Node js quick tour v2
Wyatt Fang
 
Webdevcon Keynote hh-2012-09-18
Webdevcon Keynote hh-2012-09-18Webdevcon Keynote hh-2012-09-18
Webdevcon Keynote hh-2012-09-18
Pierre Joye
 
The Robot Operating System ecosystem and Python
The Robot Operating System ecosystem and PythonThe Robot Operating System ecosystem and Python
The Robot Operating System ecosystem and Python
Esteve Fernández
 
Real-time Web with Rails and XMPP
Real-time Web with Rails and XMPPReal-time Web with Rails and XMPP
Real-time Web with Rails and XMPP
Li Cai
 

Similar to 1 year with ROM on production (20)

Node js quick-tour_v2
Node js quick-tour_v2Node js quick-tour_v2
Node js quick-tour_v2
 
Node js quick-tour_v2
Node js quick-tour_v2Node js quick-tour_v2
Node js quick-tour_v2
 
Node js quick tour v2
Node js quick tour v2Node js quick tour v2
Node js quick tour v2
 
Google App Engine Java, Groovy and Gaelyk
Google App Engine Java, Groovy and GaelykGoogle App Engine Java, Groovy and Gaelyk
Google App Engine Java, Groovy and Gaelyk
 
Introduction to REST API with Node.js
Introduction to REST API with Node.jsIntroduction to REST API with Node.js
Introduction to REST API with Node.js
 
Webdevcon Keynote hh-2012-09-18
Webdevcon Keynote hh-2012-09-18Webdevcon Keynote hh-2012-09-18
Webdevcon Keynote hh-2012-09-18
 
The Robot Operating System ecosystem and Python
The Robot Operating System ecosystem and PythonThe Robot Operating System ecosystem and Python
The Robot Operating System ecosystem and Python
 
Saving Money with Open Source GIS
Saving Money with Open Source GISSaving Money with Open Source GIS
Saving Money with Open Source GIS
 
ROS and Unity.pdf
ROS and Unity.pdfROS and Unity.pdf
ROS and Unity.pdf
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
Java プログラマーのための Swift 入門 #中央線Meetup
Java プログラマーのための Swift 入門 #中央線MeetupJava プログラマーのための Swift 入門 #中央線Meetup
Java プログラマーのための Swift 入門 #中央線Meetup
 
Going Offline with JS
Going Offline with JSGoing Offline with JS
Going Offline with JS
 
Real-time Web with Rails and XMPP
Real-time Web with Rails and XMPPReal-time Web with Rails and XMPP
Real-time Web with Rails and XMPP
 
Node.js
Node.jsNode.js
Node.js
 
Ractor's speed is not light-speed
Ractor's speed is not light-speedRactor's speed is not light-speed
Ractor's speed is not light-speed
 
JRuby, Ruby, Rails and You on the Cloud
JRuby, Ruby, Rails and You on the CloudJRuby, Ruby, Rails and You on the Cloud
JRuby, Ruby, Rails and You on the Cloud
 
How to Make Norikra Perfect
How to Make Norikra PerfectHow to Make Norikra Perfect
How to Make Norikra Perfect
 
Kasza smashing the_jars
Kasza smashing the_jarsKasza smashing the_jars
Kasza smashing the_jars
 
ROS+GAZEBO
ROS+GAZEBOROS+GAZEBO
ROS+GAZEBO
 
How to Contribute to Apache Usergrid
How to Contribute to Apache UsergridHow to Contribute to Apache Usergrid
How to Contribute to Apache Usergrid
 

Recently uploaded

%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 

Recently uploaded (20)

WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 

1 year with ROM on production

  • 1. @gotar | @oskarszrajer gotar.info Oskar Szrajer
  • 2. One year with on production
  • 3. What is ROM (Ruby Object Mapper) https://github.com/orgs/rom-rb PERSISTENCE & MAPPING TOOLKIT FOR RUBY http://rom-rb.org
  • 4. Author of ROM Piotr Solnica | @_solnic_ | http://solnic.eu author of ROM, Virtus, Dry-*, Rodakase, ...
  • 5. Community • dozen of devs • very active Gitter channel https://gitter.im/rom-rb/chat • stable API >1.0v • battle tested on production
  • 6. History of ROM • successor of DataMapper - aka DataMapper v2 • first commit - Feb 1 2012 • first version - v0.1 - Jun 15 2013 • first public version - v0.6 - Mar 22, 2015 • v1.0 - stable API - Jan 6, 2016
  • 7. Core ideas • reduced global state to minimum • immutability • mix OO with FP • blazing fast
  • 8. Core concepts • Configuration • Relations • Commands • Mappers
  • 9. Configuration require 'rom' config = ROM::Configuration.new( :sql, 'postgres://localhost/rom_repo' ) rom = ROM.container(config) rom.gateways[:default] # #<ROM::SQL::Gateway:0x007fde7a087158>
  • 10. ROM::Configuration.new( default: [:sql, 'postgres://localhost/db'], legacy: [:sql, 'mysql://localhost/legacy_db'], marketing: [:yesql, 'postgres://localhost/db', path: './sql'], cache: [:redis, 'redis://localhost'], csv: [:csv, File.expand_path('./data.csv', __FILE__], events: [:event_store, '127.0.0.1:1113'] # ... )
  • 11. Relations class Users < ROM::Relation[:sql] def by_id(id) where(id: id) end end rom.relation(:users).by_id(1).to_a # [{:id=>1, :name=>"Jane"}]
  • 12. Everything is lazy (callable) rom.relation(:users).by_id(1) #<Db::Relations::Users dataset=#<Sequel::Postgres::Dataset: "SELECT "id", ... rom.relation(:users).by_id(1).call # [{:id=>1, :name=>"Jane"}] rom.relation(:users).by_id(1).only(:id).to_a # [{:id=>1}] rom.relation(:users).by_id(1).only(:id).one # {:id=>1}
  • 13. Commands class Create < ROM::Commands::Create[:sql] relation :users register_as :create result :one end create_user = rom.command(:users).create create_user.call(name: 'Jack') # {id: 2, name: 'Jack'}
  • 14. class Create < ROM::Commands::Create[:sql] relation :users register_as :create input NewUserParams validator UserValidator result :one end
  • 15. class AuthorWithBooks < ROM::Commands::Create[:sql] #... end create_authors_with_books = rom.command(:authors) do |authors| authors.create(:books) end create_authors_with_books[authors: evaluated_authors] # {:id=>1, :code=>"jd001", :name=>"Jane Doe", :email=>"jane@doe.org"} # {:id=>1, :author_id=>1, :title=>"First", :published_on=>#<Date: 2010-10-10 ((2455480j, 0s,0n),+0s,2299161j)>} # {:id=>2, :author_id=>1, :title=>"Second", :published_on=>#<Date: 2011-11-11 ((2455877j, 0s,0n),+0s,2299161j)>} # {:id=>3, :author_id=>1, :title=>"Third", :published_on=>#<Date: 2012-12-12 ((2456274j, 0s,0n),+0s,2299161j)>}
  • 16. Mappers class UsersMapper < ROM::Mapper relation :users register_as :entity attribute :id attribute :name attribute :age do rand(18..90) end end
  • 17. users = rom.relation(:users).as(:entity) users.call [ { id: 1, name: "Jane", age: 22 }, { id: 2, name: "Jack", age: 64 } ]
  • 18. Pipelines (everything that responds to #call can be a mapper) only_name = -> input { input.map{|u| u[:name]} } upcase = -> input { input.map{|x| x.upcase} } users = rom.relation(:users) result = users >> only_name >> upcase result.to_a > ["JANE", "JACK"]
  • 19. Domain data types & Repositories class User < Dry::Types::Value attribute :name, Types::Strict::String end class UserRepo < ROM::Repository relation :users def all users.select(:name).as(User).to_a end end
  • 20. user_repo = UserRepo.new(rom) user_repo.all > [#<User name="Jane">, #<User name="Jack">]
  • 22.
  • 24. Both project use similar technologies: • Roda (as HTTP layer) • ROM • Yaks (JSON API)
  • 25. Request cycle ParamsObject >> Validator >> ROM >> Mapper(s) >> JSON API Mapper Mapping & coercion layer Mapping & coercion layer combine (or change) data convert data to json api format CQRS
  • 26. combining data class UserRepository < ROM::Repository::Base relations :users, :tasks def with_tasks(id) users.by_id(id).combine_children(many: tasks) end end user_repo.with_tasks.to_a # [#<ROM::Struct[User] id=1 name="Jane" tasks=[#<ROM::Struct[Task] id=2 user_id=1 title="Jane Task">]>, #<ROM::Struct[User] id=2 name="Jack" tasks=[#<ROM::Struct[Task] id=1 user_id=2 title="Jack Task">]>]
  • 27. pros • separating persistence from application & encouraging that boundary • ability to choose appropriate storage (SQL, NoSQL, ...), but keeping the same API • possibility to pull from different data sources, and combine everything together
  • 28. pros • easy way to map (manipulate, coerce) data • freedom • community
  • 29. cons • commands (right now repository do not support them, force to use very low level API, should be done before v2) • hard to learn (many new concepts) • lack of documentation (community will help you) (currently community works to fix it, and there is always someone sitting on Gitter to help you)