Implement a Data Source Pattern for a Multi-Model NoSQL ...€¦ · Implement a Data Source Pattern...

Preview:

Citation preview

Implement a Data Source Pattern for a Multi-Model NoSQL database

or

How to make Guacamole

16.4.2014 / cologne.rb / @mixxtDirk Breuer / @railsbros_dirk

Data Source Pattern

Architectural patterns which drive the way in which the domain logic

talks to the database.

– Martin Fowler

• Active Record

• Data Mapper

• Table Data Gateway

• Row Data Gateway

• …

NoSQL

Not ACID compliant

Big DataDistributed

Web Scale

ROFL Scale

CAP

Documents

Flexible

High Availability

NoSQL Databases

• „Not only SQL“

• Not one definition

• Sometimes just a marketing buzz-fuzz

Classifications

• Document-based

• Key-Value stores

• Graph-based

• Column stores

• Time series

Aggregate-based}

Multi-Model

Combine more than one approach within one database system

Guacamole

Source: https://en.wikipedia.org/wiki/File:Guacamole.jpg

A dip consisting at least of ripe avocados and salt

…and…

gem 'guacamole'An ODM for ArangoDB to be used with Rails and other Ruby frameworks*

Object Document Mapper

*which is not yet finished 😜

• Open-Source NoSQL database

• Multi-Model

• Document-based

• Graph-based

Why should I useArangoDB in favor of

<any other document store>?

With ArangoDB you can perform joinsover your documents similar

to joins in relational databases.

Before you start

Patterns of Enterprise Application Architecture

Ingredients

1 Design Goal

1 Data Source Pattern

3 📦 Supporting Libraries

1 Database driver

1 solid Test-Suite

1 📦 Documentation

Design Goal

• Support building web applications with Ruby on Rails or other Rack-based frameworks

• Focus on easy integration in Views and the general workflow

• Reflect the nature of NoSQL in general and ArangoDB in particular

Data Source Pattern

Data MapperIt’s a

Nein! – Doch! – Ohhh

h!

+ Testability is increased

+ Separation of Concern

+ Easier to support databasefeatures like embedded objects

- The average Rails dev isused to Active Record

- Starting with Data Mapper requires more effort

Supporting Libraries

spec.add_dependency 'ashikawa-core' spec.add_dependency 'virtus' spec.add_dependency 'activemodel' spec.add_dependency 'hamster' spec.add_dependency 'activesupport'

Implementation

Just some bits and pieces…

The Model

class Post include Guacamole::Model !

attribute :title, String attribute :body, String attribute :comments, Array[Comment] attribute :user, User end

The Collection (a.k.a. The Mapper)

class PostsCollection include Guacamole::Collection !

map do embeds :comments references :user end end

ActiveRecord equivalent

class Post < ActiveRecord belongs_to :user has_many :comments end

Retrieving Data

# Get a user by email UsersCollection.by_example(email: "p.pie@cupcakes.com")

Identity Map

„Ensures that each object gets loaded only once by keeping every loaded object in a map. Looks up objects

using the map when referring to them.“

– Martin Fowler

• Not a Cache!

• Every session needs its own, fresh instance

• Should be suited for concurrency (you know, just in case)

module Guacamole class IdentityMap class << self def store(object) @_map = _map.put(key_for(object), object) object end !

def retrieve(klass, key) _map.get key_for(klass, key) end !

def _map @_map ||= Hamster.hash end end end end

Lazy Loading

Post#user

#<User>

Proxy

UsersCollection.by_key(post_document[:user_key])

Active Model compliance

• Really useful, not only for Rails

• A lot of Gems build on top of Active Model

• A lot of useful features (i.e. Validations)

• Not related to the Active Record pattern

Caveats

rom-rb/devtools

Virtus and Circular Dependencies

class Author extend ActiveSupport::Autoload include Guacamole::Model !

autoload :Book, 'models/book' !

attribute :name, String attribute :books, Array[Book] end

class Book extend ActiveSupport::Autoload include Guacamole::Model !

autoload :Author, 'models/author' !

attribute :title, String attribute :author, Author end

This is not very Ruby

Next Steps

Support for Arango Query Language (AQL)

Support for Transactions

Support the Graph API

https://github.com/triAGENS/guacamole

Get a Nacho and dip in

http://tfcl.de/

http://geekstammtisch.de/

https://github.com/railsbros-dirk

Thanks

Recommended