Your SlideShare is downloading. ×
Building Web Service Clients with ActiveModel
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Building Web Service Clients with ActiveModel

1,836

Published on

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,836
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
17
Comments
0
Likes
5
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide





















































































































  • Transcript

    • 1. Building Web Service Clients with ActiveModel Paul Dix http://pauldix.net @pauldix
    • 2. IM Paul Dix photo credit: Sebastian Delmont
    • 3. I am a Ruby love machine!
    • 4. Web Services, duh!
    • 5. ActiveModel
    • 6. Web Services Abstract Complexity
    • 7. Scale
    • 8. Scale with Complexity PhOtOnQuAnTiQuE (http://www.flickr.com/photos/67968452@N00/1876685709/)
    • 9. Scale with Team Size alexkess (http://www.flickr.com/photos/34838158@N00/3370167184/)
    • 10. Monolithic American Backroom (http://www.flickr.com/photos/41922098@N03/4247207167/)
    • 11. Split into Logical Parts
    • 12. How ActiveResource killed my best friend
    • 13. Brian Hathcock (http://www.flickr.com/photos/22961976@N00/3040920714/)
    • 14. Understandable Code
    • 15. Client libraries goal: readable and maintainable code
    • 16. Parallel Connections
    • 17. Make Stubbing Easy for Development
    • 18. define:”Web Services”
    • 19. External Services
    • 20. Internal Services
    • 21. ActiveModel is for use with rails forms helpers and other things. Things that are only used inside user requests. Calls Inside User Requests
    • 22. focus(:internal_services)
    • 23. Abstracting Complexity
    • 24. Work with large code base
    • 25. Scale
    • 26. Not Traffic
    • 27. NoSQL is getting there
    • 28. Code Complexity
    • 29. Team Size
    • 30. Examples
    • 31. Processor
    • 32. Operating System
    • 33. MapReduce
    • 34. Web Services?
    • 35. Email Service
    • 36. User Service
    • 37. Haystack
    • 38. Indexing
    • 39. How to separate functionality
    • 40. Partition on Iteration Speed
    • 41. Partition on Logical Fucntion
    • 42. Partition on Read/Write Frequencies
    • 43. Partition on Join Frequency
    • 44. Goals
    • 45. Denormalize and Replicate
    • 46. Separation of Concerns
    • 47. Abstraction
    • 48. ActiveResource and ActiveRecord killed these
    • 49. Both make connections inside the model
    • 50. class Collect < Base end class ShippingAddress < Base end class BillingAddress < Base end class LineItem < Base end class ShippingLine < Base end class NoteAttribute < Base end
    • 51. lloydi (http://www.flickr.com/photos/58944004@N00/2362260604/)
    • 52. class Collect < Base end class ShippingAddress < Base end class BillingAddress < Base end class LineItem < Base end class ShippingLine < Base end class NoteAttribute < Base end
    • 53. Makes requests serially
    • 54. Requests in Parallel
    • 55. ActiveModel
    • 56. helpers for adding prefixes and suffixes to methods.... boring AttributeMethods
    • 57. Callbacks
    • 58. class User include ActiveModel::Callbacks before_create :do_stuff def create # ... end def do_stuff # ... end end
    • 59. Dirty Tracking
    • 60. class Person include ActiveModel::Dirty define_attribute_methods [:name] def name @name end def name=(val) name_will_change! @name = val end def save @previously_changed = changes end end
    • 61. # A newly instantiated object is unchanged: person = Person.find_by_name('Uncle Bob') person.changed? # => false
    • 62. # Change the name: person.name = 'Bob' person.changed? # => true person.name_changed? # => true person.name_was # => 'Uncle Bob' person.name_change # => ['Uncle Bob', 'Bob'] person.name = 'Bill' person.name_change # => ['Uncle Bob', 'Bill']
    • 63. # Save the changes: person.save person.changed? # => false person.name_changed? # => false
    • 64. # Assigning the same value leaves the # attribute unchanged: person.name = 'Bill' person.name_changed? # => false person.name_change # => nil
    • 65. # Which attributes have changed? person.name = 'Bob' person.changed # => ['name'] person.changes # => {'name' => ['Bill', 'Bob']}
    • 66. # Resetting an attribute returns it to # its original state: person.reset_name! # => 'Bill' person.changed? # => false person.name_changed? # => false person.name # => 'Bill'
    • 67. Errors
    • 68. class User def errors @errors ||= ActiveModel::Errors.new(self) end def validate! errors.add(:name, "can not be nil") end end user.errors[:name] #=> ["can not be nil"]
    • 69. Serialization
    • 70. class User include ActiveModel::Serialization def attributes { :id => @id, :name => @name, :email => @email } end end user.to_json(:only => [:id, :name]) user.to_xml(:except => [:email])
    • 71. Validations
    • 72. class User include ActiveModel::Validations attr_reader :name, :email, :age, :terms_of_service, :password, :password_confirmation, :role validates_acceptance_of :terms_of_service end user = User.new puts user.valid?
    • 73. class User include ActiveModel::Validations attr_reader :name, :email, :age, :terms_of_service, :password, :password_confirmation, :role validates_confirmation_of :password end user = User.new puts user.valid?
    • 74. class User include ActiveModel::Validations attr_reader :name, :email, :age, :terms_of_service, :password, :password_confirmation, :role validates_presence_of :name end user = User.new puts user.valid?
    • 75. class User include ActiveModel::Validations attr_reader :name, :email, :age, :terms_of_service, :password, :password_confirmation, :role validates_exclusion_of :name, :in => ["admin"] end user = User.new puts user.valid?
    • 76. class User include ActiveModel::Validations attr_reader :name, :email, :age, :terms_of_service, :password, :password_confirmation, :role validates_inclusion_of :role, :in => ["user", "admin"] end user = User.new puts user.valid?
    • 77. class User include ActiveModel::Validations attr_reader :name, :email, :age, :terms_of_service, :password, :password_confirmation, :role validates_format_of :email, :with => /A([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})Z/i end user = User.new puts user.valid?
    • 78. class User include ActiveModel::Validations attr_reader :name, :email, :age, :terms_of_service, :password, :password_confirmation, :role validates_length_of :password, :minimum => 6 end user = User.new puts user.valid?
    • 79. class User include ActiveModel::Validations attr_reader :name, :email, :age, :terms_of_service, :password, :password_confirmation, :role validates_numericality_of :age end user = User.new puts user.valid?
    • 80. validates_uniqueness_of?
    • 81. ehpien (http://www.flickr.com/photos/91499534@N00/343313257/)
    • 82. Testing
    • 83. require 'rubygems' require 'active_model' require 'test/unit' require 'user' class LintTest < ActiveModel::TestCase include ActiveModel::Lint::Tests def setup @model = User.new end end
    • 84. class User include ActiveModel::Conversion extend ActiveModel::Naming def valid?() true end def errors @errors ||= ActiveModel::Errors.new(self) end def persisted? true end end
    • 85. Parallel Connections
    • 86. Asynchronous
    • 87. EventMachine
    • 88. Curb
    • 89. Typhoeus Mushkush (http://www.flickr.com/photos/43002463@N00/2877016310/)
    • 90. Quick Example
    • 91. PauldixReadingList::ReadingList.for_user( "paul", :include => [:entry, :rating_total]) do |list| reading_list = list end HYDRA.run # now we can access the reading list reading_list.entries.each do |entry| puts entry.id puts entry.title puts entry.body puts "up: #{entry.rating_total.up_count} | down: #{entry.rating_total.down_count}nn" end
    • 92. def self.for_user(user_id, options = {}, &block) includes = options[:include] || [] request = Typhoeus::Request.new(get_by_id_uri(user_id)) request.on_complete do |response| list = new(response.body, options) list.request_entries if includes.include?(:entry) list.request_rating_totals if includes.include?(:rating_total) block.call(list) end PauldixReadingList::Config.hydra.queue(request) end
    • 93. def self.get_ids(ids, &block) request = Typhoeus::Request.new(get_ids_uri(ids)) request.on_complete do |response| json = Yajl::Parser.parse(response.body) entries = ids.map do |id| new(json[id].merge("id" => id)) end block.call(entries) end PauldixEntries::Config.hydra.queue(request) end
    • 94. def self.get_ids(ids, &block) request = Typhoeus::Request.new(get_ids_uri(ids)) request.on_complete do |response| json = Yajl::Parser.parse(response.body) ratings = ids.map do |id| new(json[id]) end block.call(ratings) end PauldixRatings::Config.hydra.queue(request) end
    • 95. Gunnsi (http://www.flickr.com/photos/38735097@N00/440198755/)
    • 96. Threaded
    • 97. require 'net/http' include Java import 'java.util.concurrent.Executors' class Request include java.util.concurrent.Callable def initialize(url) @url = url end def call Net::HTTP.get(URI.parse(@url)) end end
    • 98. thread_pool = Executors.new_fixed_thread_pool(50) futures = [] 100.times do |i| request = Request.new("http://localhost:3000/entries/#{i}") futures << thread_pool.submit(request) end results = futures.map {|f| f.get} # do something with results thread_pool.shutdown
    • 99. Keep Alive
    • 100. Awesome art credit: Joe West
    • 101. Stubbing
    • 102. Review
    • 103. Readable Client Code
    • 104. lloydi (http://www.flickr.com/photos/58944004@N00/2362260604/)
    • 105. Models Build Requests
    • 106. Parallel Connections
    • 107. Validate Early
    • 108. Easy Stubs
    • 109. Abstract Complexity
    • 110. Scale
    • 111. Scale with Complexity PhOtOnQuAnTiQuE (http://www.flickr.com/photos/67968452@N00/1876685709/)
    • 112. Scale with Team Size alexkess (http://www.flickr.com/photos/34838158@N00/3370167184/)
    • 113. Monolithic American Backroom (http://www.flickr.com/photos/41922098@N03/4247207167/)
    • 114. Thanks!
    • 115. Questions?

    ×