75
Rails goes SOA Rails-Konferenz 2009 – Frankfurt/Offenbach Dirk Breuer – pkw.de 02. September 2009

Rails goes SOA

Embed Size (px)

DESCRIPTION

The slides of my talk at Rails-Konferenz 2009 in Frankfurt/Offenbach about bringing together the ideas of SOA with Rails to handle complexity.

Citation preview

Page 1: Rails goes SOA

Rails goes SOARails-Konferenz 2009 – Frankfurt/Offenbach

Dirk Breuer – pkw.de

02. September 2009

Page 2: Rails goes SOA

View

Model(enthält Business Logik + Daten)

Controller (nur lesend)

Page 3: Rails goes SOA

View

Model(enthält Business Logik)

Controller

BusinessLogik

(nur lesend)

Page 4: Rails goes SOA

View

Model(Datenhaltung)

Controller(nur lesend)Business

Logikextract

Page 5: Rails goes SOA

Vorteile der Transformation

Entwickler erhalten Kontrolle über Source Code zurück

Bessere Verständlichkeit für die Fachseite

Grafik © by Martin Laksman, 2003

Page 6: Rails goes SOA

Vorteile der Transformation

Entwickler erhalten Kontrolle über Source Code zurück

Bessere Verständlichkeit für die Fachseite

Bessere Time-to-Market

Grafik © by Martin Laksman, 2003

Page 7: Rails goes SOA

Service-Orientierte Architekturen

Page 8: Rails goes SOA

View

Model(Datenhaltung)

Controller(nur lesend)Services

(enthalten Business Logik)

Page 9: Rails goes SOA

How To SOA?

Page 10: Rails goes SOA
Page 11: Rails goes SOA

Fahrzeuge Suchen

Page 12: Rails goes SOA

Fahrzeuge fürdie Startseite

anzeigen

Page 13: Rails goes SOA
Page 14: Rails goes SOA

Suchauftrag fürSuche anlegen

Page 15: Rails goes SOA

Benutzerauthentifizieren

Page 16: Rails goes SOA
Page 17: Rails goes SOA

Statistiken fürein Fahrzeug

anzeigen

Page 18: Rails goes SOA

Statistiken fürein Fahrzeug

anzeigen

StatistikenSchreiben

Page 19: Rails goes SOA

get_startpage_carsget_startpage_dealerget_startpage_teasersearch_carscreate_temporary_customercreate_temporary_carsave_temporary_customersave_temporary_carauthenticate_customeradd_image_to_cargenerate_captchaverify_captchaaccept_customerpublish_carnotify_customer_about_published_car

get_statistics_of_carget_number_of_cars_of_customerget_cars_of_customerget_number_of_car_imagesget_car_imagesdelete_cardelete_customerget_search_orders_of_customerdelete_search_ordersearch_cars_by_search_orderauthenticate_customerauthenticate_dealergenerate_passwordsend_new_password…

Page 20: Rails goes SOA

Vorteile von SOA

Services werden von Fachseite gefunden

Fachseite versteht IT besser

Fachseite versteht Komplexität besser

Fachliche Sicht sehr langlebig, dadurch Services sehr langlebig

Page 21: Rails goes SOA

Vorteile von SOA

Services werden von Fachseite gefunden

Fachseite versteht IT besser

Fachseite versteht Komplexität besser

Fachliche Sicht sehr langlebig, dadurch Services sehr langlebig

Langlebigkeit ...?

Gra

fik ©

by

Mar

tin L

aksm

an, 2

003

Page 22: Rails goes SOA

Langlebigkeit der Datenbank?

Änderung von Spalten

Änderung des CRM-Systems

Anbindung an SAP

Zusammenlegung von StartUps

Page 23: Rails goes SOA

Langlebigkeit der GUI?

Änderung der Anordnung von Elementen

Änderung von Dialogen

Änderung von Texten

Redesign der gesamten Plattform

Page 24: Rails goes SOA

Langlebigkeit von Services

Fachseite definiert Geschäftsprozesse

Fahrzeuge suchen

Benutzer authentifizieren

Statistiken schreiben

Änderungen auf dieser Ebene sehr viel unwahrscheinlicher

Page 25: Rails goes SOA

Und was genau ist ein Service Jetzt?!

Grafik © by Martin Laksman, 2003

Page 26: Rails goes SOA

Ein Service ist …

… technologie- und plattformunabhängig

… dynamische lokalisier- und ausführbar

… in sich abgeschlossen

… durch eine wohl-definierte und formale Schnittstelle beschrieben

… stateless

Page 27: Rails goes SOA

Dienstbeschreibungveröffentlichen

Dienstimplementierungbinden

Dienstbeschreibungfinden

Service Registry

Service Provider

Service Client

Basic SOA

Page 28: Rails goes SOA

Aber kosten diese SOA Lösungen von IBM & Co nicht

sehr viel Geld?

Grafik © by Martin Laksman, 2003

Page 29: Rails goes SOA

Ja ...

Aber kosten diese SOA Lösungen von IBM & Co nicht

sehr viel Geld?

Grafik © by Martin Laksman, 2003

Page 30: Rails goes SOA

Das können wir uns nicht leisten!

Ja ...

Aber kosten diese SOA Lösungen von IBM & Co nicht

sehr viel Geld?

Grafik © by Martin Laksman, 2003

Page 31: Rails goes SOA

SOA ist doch nur ein Konzept. Das können

wir auch selbst umsetzen.

Grafik © by Martin Laksman, 2003

Page 32: Rails goes SOA

SOA ist doch nur ein Konzept. Das können

wir auch selbst umsetzen.

Und zwar passendfür uns!

Grafik © by Martin Laksman, 2003

Page 33: Rails goes SOA

+ SOA

Page 34: Rails goes SOA

class SearchService

def self.search_cars(search_criteria) # Calling the Car class which is just # a ActiveRecord::Base subclass end

end

found_cars = SearchService.search_cars(some_criteria)

Page 35: Rails goes SOA

class SearchService

def self.search_cars(search_criteria) # Calling the Car class which is just # a ActiveRecord::Base subclass end

end

found_cars = SearchService.search_cars(some_criteria)

Aber moment, das sieht

Page 36: Rails goes SOA

class Car < ActiveRecord::Base

def self.search(criteria) find(:all, :conditition => criteria) end

end

found_cars = Car.search(params[:criteria])

Page 37: Rails goes SOA

class Car < ActiveRecord::Base

def self.search(criteria) find(:all, :conditition => criteria) end

end

found_cars = Car.search(params[:criteria])Aber ...

Page 38: Rails goes SOA

Echte Businesslogik ist in der Regel deutlich komplexer

Bisher: ActiveRecord::Base = Businesslogik + Daten

Jetzt: ActiveRecord::Base = Daten, Service = Businesslogik

Page 39: Rails goes SOA

Echte Businesslogik ist in der Regel deutlich komplexer

Bisher: ActiveRecord::Base = Businesslogik + Daten

Jetzt: ActiveRecord::Base = Daten, Service = Businesslogik

inkl. einfacher Validierung etc.

Page 40: Rails goes SOA

Verteilung

Statistic Service

Such Service

SuchauftragService

AuthentifizierungsService

RailsFrontend

Page 41: Rails goes SOA

Verteilung

Statistic Service

Such Service

SuchauftragService

AuthentifizierungsService

RailsFrontend

?

?

?

Page 42: Rails goes SOA

Verteilung

Statistic Service

Such Service

SuchauftragService

AuthentifizierungsService

RailsFrontend

?

?

?Thrift-RPC

Page 43: Rails goes SOA

Thrift-RPC?!?

Grafik © by Martin Laksman, 2003

Page 44: Rails goes SOA

Thrift-RPC

RPC-Framework von Facebook entwickelt

Mittlerweile Apache Incubator Projekt: http://incubator.apache.org/thrift/

Ziel: Verlässliche und effiziente Kommunikation verteilter Systemkomponenten

Page 45: Rails goes SOA

Thrift-Architektur

Transport

Protocol

Processor

Service-Implementierung

Page 46: Rails goes SOA

Thrift-Architektur

Transport

Protocol

Processor

Service-Implementierung

Thrift-Compiler

Thrift-Gem

Page 47: Rails goes SOA

Thrift ServiceDefinitionerstellen

Page 48: Rails goes SOA

Thrift ServiceDefinitionerstellen

Service Stubsgenerieren

Page 49: Rails goes SOA

Thrift ServiceDefinitionerstellen

Service Stubsgenerieren

Serviceimplementieren

Page 50: Rails goes SOA

Thrift ServiceDefinitionerstellen

Transport-Schicht

realisierenService Stubsgenerieren

Serviceimplementieren

Page 51: Rails goes SOA

Thrift ServiceDefinitionerstellen

Transport-Schicht

realisierenService Stubsgenerieren

Serviceimplementieren

Serviceansprechen

Page 52: Rails goes SOA

Thrift ServiceDefinitionerstellen

Transport-Schicht

realisierenService Stubsgenerieren

Serviceimplementieren

Serviceansprechen

Page 53: Rails goes SOA

Thrift Service-Definition

namespace rb UserService

enum UserStates { VERIFIED = 1, UNVERIFIED = 2, BLOCKED = 3}

struct User { 1: string firstname, 2: string lastname, 3: i32 age, 4: string email, 5: string username, 6: UserStates state}

exception AuthenticationError { 1: string message, 2: list<string> backtrace}

service AuthenticationService { User authenticate_user(1:string username, 2:string password)throws (1:AuthenticationError ae)}

Page 54: Rails goes SOA

Thrift Service-Definition

✓Namespacesnamespace rb UserService

enum UserStates { VERIFIED = 1, UNVERIFIED = 2, BLOCKED = 3}

struct User { 1: string firstname, 2: string lastname, 3: i32 age, 4: string email, 5: string username, 6: UserStates state}

exception AuthenticationError { 1: string message, 2: list<string> backtrace}

service AuthenticationService { User authenticate_user(1:string username, 2:string password)throws (1:AuthenticationError ae)}

Page 55: Rails goes SOA

Thrift Service-Definition

✓Namespaces

✓Enums

namespace rb UserService

enum UserStates { VERIFIED = 1, UNVERIFIED = 2, BLOCKED = 3}

struct User { 1: string firstname, 2: string lastname, 3: i32 age, 4: string email, 5: string username, 6: UserStates state}

exception AuthenticationError { 1: string message, 2: list<string> backtrace}

service AuthenticationService { User authenticate_user(1:string username, 2:string password)throws (1:AuthenticationError ae)}

Page 56: Rails goes SOA

Thrift Service-Definition

✓Namespaces

✓Enums

✓Primitive Datentypen

namespace rb UserService

enum UserStates { VERIFIED = 1, UNVERIFIED = 2, BLOCKED = 3}

struct User { 1: string firstname, 2: string lastname, 3: i32 age, 4: string email, 5: string username, 6: UserStates state}

exception AuthenticationError { 1: string message, 2: list<string> backtrace}

service AuthenticationService { User authenticate_user(1:string username, 2:string password)throws (1:AuthenticationError ae)}

Page 57: Rails goes SOA

Thrift Service-Definition

✓Namespaces

✓Enums

✓Primitive Datentypen

✓Komplexe Typen

namespace rb UserService

enum UserStates { VERIFIED = 1, UNVERIFIED = 2, BLOCKED = 3}

struct User { 1: string firstname, 2: string lastname, 3: i32 age, 4: string email, 5: string username, 6: UserStates state}

exception AuthenticationError { 1: string message, 2: list<string> backtrace}

service AuthenticationService { User authenticate_user(1:string username, 2:string password)throws (1:AuthenticationError ae)}

Page 58: Rails goes SOA

Thrift Service-Definition

✓Namespaces

✓Enums

✓Primitive Datentypen

✓Komplexe Typen

✓Exceptions

namespace rb UserService

enum UserStates { VERIFIED = 1, UNVERIFIED = 2, BLOCKED = 3}

struct User { 1: string firstname, 2: string lastname, 3: i32 age, 4: string email, 5: string username, 6: UserStates state}

exception AuthenticationError { 1: string message, 2: list<string> backtrace}

service AuthenticationService { User authenticate_user(1:string username, 2:string password)throws (1:AuthenticationError ae)}

Page 59: Rails goes SOA

Thrift Service-Definition

✓Namespaces

✓Enums

✓Primitive Datentypen

✓Komplexe Typen

✓Exceptions

✓Services

namespace rb UserService

enum UserStates { VERIFIED = 1, UNVERIFIED = 2, BLOCKED = 3}

struct User { 1: string firstname, 2: string lastname, 3: i32 age, 4: string email, 5: string username, 6: UserStates state}

exception AuthenticationError { 1: string message, 2: list<string> backtrace}

service AuthenticationService { User authenticate_user(1:string username, 2:string password)throws (1:AuthenticationError ae)}

Page 60: Rails goes SOA

Walkthrough: Statistik-Service

Page 61: Rails goes SOA

namespace rb Pkwde.StatisticsModule

struct Statistic { 1:string name, 2:i32 count}

service StatisticsService { list<Statistic> statistic_for(1:list<string> element_names), oneway void increment(1:list<string> elements)}

$> thrift --gen rb:rails -o ./app/thrift config/statistics_service.thrift

app/thrift`-- gen-rb `-- pkwde `-- statistics_module |-- statistics_service.rb |-- statistics_service_constants.rb `-- statistics_service_types.rb

Page 62: Rails goes SOA

class StatisticsHandler def statistic_for(element_names) Statistic.find_all_by_name(element_names).map do |statistic| Pkwde::StatisticsModule::Statistic.new(:name => statistic.name, :count => statistic.count) end end def increment(elements) elements.each do |element| Statistic.find_or_create_by_name(element).increment!(:count) end end end

Page 63: Rails goes SOA

require 'thrift/server/rack_middleware'

ActionController::Dispatcher.middleware.insert_before(Rails::Rack::Metal, Thrift::RackMiddleware, { :processor => Pkwde::StatisticsModule::StatisticsService::Processor.new(StatisticsHandler.new), :hook_path => "/statistics" })

Service Provider

StatisticsHandler.new

Page 64: Rails goes SOA

require 'thrift/server/rack_middleware'

ActionController::Dispatcher.middleware.insert_before(Rails::Rack::Metal, Thrift::RackMiddleware, { :processor => Pkwde::StatisticsModule::StatisticsService::Processor.new(StatisticsHandler.new), :hook_path => "/statistics" })

Service Provider

StatisticsHandler.new

Page 65: Rails goes SOA

require 'thrift/server/rack_middleware'

ActionController::Dispatcher.middleware.insert_before(Rails::Rack::Metal, Thrift::RackMiddleware, { :processor => Pkwde::StatisticsModule::StatisticsService::Processor.new(StatisticsHandler.new), :hook_path => "/statistics" })

statistics_client = ThriftClient.new(:url => "http://localhost:3000/statistics", :client_class => Pkwde::StatisticsModule::StatisticsService::Client)

Service Provider

Service Client

StatisticsHandler.new

Page 66: Rails goes SOA

require 'thrift/server/rack_middleware'

ActionController::Dispatcher.middleware.insert_before(Rails::Rack::Metal, Thrift::RackMiddleware, { :processor => Pkwde::StatisticsModule::StatisticsService::Processor.new(StatisticsHandler.new), :hook_path => "/statistics" })

statistics_client = ThriftClient.new(:url => "http://localhost:3000/statistics", :client_class => Pkwde::StatisticsModule::StatisticsService::Client)

Service Provider

Service Client

http://github.com/railsbros/thrift4rails

http://github.com/railsbros/thrift

StatisticsHandler.new

Page 67: Rails goes SOA
Page 68: Rails goes SOA

Was ist Eigentlich mit einer Lösung die mehr

Ruby ist …?

Grafik © by Martin Laksman, 2003

Page 69: Rails goes SOA

Hoth::Services.define do service :increment_statistics, :params => [[:element]], :returns => nil, :endpoint => :statistics_module service :statistic_for, :params => [[:element_name]], :returns => [:statistic], :endpoint => :statistics_module end

Sneak Preview

Service-Definition

Page 70: Rails goes SOA

Hoth::ServiceDeployment.define do service_module :statistics_module do env :test, { :endpoint => Hoth::Endpoint.new(:host => 'localhost', :port => 3000), :mongrel_servers => 2, :mongrel_start_port => 9001 }

path "services/search_service" endend

Sneak Preview

Deployment-Definition

Page 71: Rails goes SOA

ENV["LOCAL"] = "false"

require 'hoth'require 'deployment_definition'require 'service_definition'

Hoth::Services.increment_statistics([statistic_object], event)Hoth::Services.statistic_of_cars([23]).inspect

Sneak Preview

Service-Client

Page 72: Rails goes SOA

ENV["LOCAL"] = "true"

require 'hoth'require 'deployment_definition'require 'service_definition'

class IncrementStatisticsImpl def self.execute(elements) elements.each do |element| Statistic.find_or_create_by_name(element).increment!(:count) end endend

class StatisticForImpl def self.execute(element_names) Statistic.find_all_by_name(element_names) endend

app = lambda {|env| [200, {'Content-Type' => 'text/plain'}, ""]}run Hoth::ServiceProvider.new(app)

Service-Provider

Page 73: Rails goes SOA

About Me …

Rubyist und Rails-Enthusiast seit Ende 2005

Software-Entwickler bei pkw.de seit 2007

Twitter: @railsbros_dirk

GitHub: http://github.com/pkwde

Blog: http://railsbros.de

Page 74: Rails goes SOA

Kann ich das gleiche nicht durch ein

gutes OO-Design realisieren?

Grafik © by Martin Laksman, 2003

Page 75: Rails goes SOA

SOA vs. OOP

SOA ersetzt OOP nicht!

SOA setzt auf einer anderen Ebene an

OOP Design Prinzipien finden jedoch keine Anwendung für SOA

Fokus auf die Abbildung von Geschäftsprozessen

Ein Service kann intern immer noch OOP sein