Making and Breaking
  Web Services
   (with Ruby)
      Chris Wanstrath
          Err Free
     http://errfree.com
ttp://farm1.static.flickr.com/138/320699460_b8e7c1e7e6_o.jpg
SOAP
• Simple Object Access Protocol?
• Lies.
• Service Oriented Architecture Protocol
• wtf.
Newsletters!
“Outbound”

• Slow response time
• Duplication of data
• Hard to debug
• require ‘soap/wsdlDriver’
Ruby SOAP Library:
      Your Friend

• Creates methods on the fly
• Seems to work pretty well
• Transparently converts Rub...
Ruby SOAP Library:
      Your Enemy

• Hard to debug (dump req/res to file)
• No one has ever used it
• There are not any a...
Why use SOAP?


• One reason: legacy.
Wrapping SOAP
def update_user(email, subs = [], unsubs = [])
  client.updateUser(brand, email, email, demo, subs, unsubs)
end
Wrapping SOAP
def update_user(email, subs = [], unsubs = [])
  client.updateUser(brand, email, email, demo, subs, unsubs)
...
Wrapping SOAP
def update_user(email, subs = [], unsubs = [])
  client.updateUser(brand, email, email, demo, subs, unsubs)
...
Wrapping SOAP
def update_user(email, subs = [], unsubs = [])
  client.updateUser(brand, email, email, demo, subs, unsubs)
...
Testing SOAP


• Use mocks
• Mocha: http://mocha.rubyforge.org
Testing SOAP

def test_get_user_should_hit_client
  email = 'chrisw@nstrath.com'
  Outbound.client.expects(:getUser).with(...
Testing SOAP

soap_methods = {
  :getUser    => true,
  :updateUser => true
}

Outbound.stubs(:client).returns(mock('SOAP ...
Running a SOAP Server
       in Ruby
Just Kidding
Microformats!
• Your website is your API
• Plant classes in HTML
• Tell parsers what information is important
• http://mic...
hReview
hReview
<div id="review_16873" class="hreview">
  <h5 class="item"><span class="fn">Beringer California Collection White M...
hReview
<div id="review_16873" class="hreview">
  <h5 class="item"><span class="fn">Beringer California Collection White M...
mofo
$ sudo gem install mofo
Successfully installed mofo-0.2.2
$ irb -rubygems
>> require 'mofo/hreview'
=> true
>> review...
mofo/hreview.rb
class HReview < Microformat
  one :version, :summary, :type, :dtreviewed,
      :rating, :description

 on...
microformat.rb
def collector
  collector = Hash.new([])
  def collector.method_missing(method, *classes)
    super unless ...
mofo supports...

              • xoxo
• hCard
              • geo
• hCalendar
              • adr
• hReview
             ...
What else can they do?
Operator
Operator
Okay.
Hpricot




( by _why )
Hpricot
$ irb -rubygems -r'open-uri'
>> require 'hpricot'
=> true
>> page = Hpricot open('http://google.com')
=> #<Hpricot...
Hpricot
Can use XPATH, CSS selectors, whatever, to search
Hpricot

>>   page = Hpricot(open('http://brainspl.at'))
=>   #<Hpricot::Doc ...>
>>   page.search('.post').size
=>   10
Hpricot
>>   corkd = 'http://corkd.com/wine/view/21670'
=>   'http://corkd.com/wine/view/21670'
>>   page = Hpricot(open(c...
Hpricot/:mofo
>> page.at('.hreview').at('.item').at('.fn').inner_text
=> "Beringer California Collection White Merlot 2005...
Oh, you can use Hpricot
     for XML, too.
  <Export>
    <Product>
      <SKU>403276</SKU>
      <ItemName>Trivet</ItemNa...
Oh, you can use Hpricot
         for XML, too.
fields = %w(SKU ItemName CollectionNo Pages)

doc = Hpricot(open("my.xml"))...
But who uses XML?
Cheat!
     http://cheat.errtheblog.com


(insert short, live demo here)
Thanks
•   http://mofo.rubyforge.org

•   http://code.whytheluckystiff.net/hpricot

•   https://addons.mozilla.org/en-US/fi...
Thanks

•   http://ronrothman.com/gallery/cnet/cnet_neon

•   http://flickr.com/photos/bootbearwdc/466751240/

•   http://fl...
Making and Breaking Web Services with Ruby
Making and Breaking Web Services with Ruby
Making and Breaking Web Services with Ruby
Making and Breaking Web Services with Ruby
Upcoming SlideShare
Loading in...5
×

Making and Breaking Web Services with Ruby

11,264

Published on

Mainly about SOAP and Microformats and Newsletters.

Published in: Business, Technology
1 Comment
8 Likes
Statistics
Notes
No Downloads
Views
Total Views
11,264
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
264
Comments
1
Likes
8
Embeds 0
No embeds

No notes for slide

Transcript of "Making and Breaking Web Services with Ruby"

  1. 1. Making and Breaking Web Services (with Ruby) Chris Wanstrath Err Free http://errfree.com
  2. 2. ttp://farm1.static.flickr.com/138/320699460_b8e7c1e7e6_o.jpg
  3. 3. SOAP • Simple Object Access Protocol? • Lies. • Service Oriented Architecture Protocol • wtf.
  4. 4. Newsletters!
  5. 5. “Outbound” • Slow response time • Duplication of data • Hard to debug • require ‘soap/wsdlDriver’
  6. 6. Ruby SOAP Library: Your Friend • Creates methods on the fly • Seems to work pretty well • Transparently converts Ruby types to SOAP definitions
  7. 7. Ruby SOAP Library: Your Enemy • Hard to debug (dump req/res to file) • No one has ever used it • There are not any alternatives • The code is a jungle
  8. 8. Why use SOAP? • One reason: legacy.
  9. 9. Wrapping SOAP def update_user(email, subs = [], unsubs = []) client.updateUser(brand, email, email, demo, subs, unsubs) end
  10. 10. Wrapping SOAP def update_user(email, subs = [], unsubs = []) client.updateUser(brand, email, email, demo, subs, unsubs) end def get_user(email) client.getUser(email, brand) end
  11. 11. Wrapping SOAP def update_user(email, subs = [], unsubs = []) client.updateUser(brand, email, email, demo, subs, unsubs) end def get_user(email) client.getUser(email, brand) end
  12. 12. Wrapping SOAP def update_user(email, subs = [], unsubs = []) client.updateUser(brand, email, email, demo, subs, unsubs) end def get_user(email) client.getUser(email, brand) end
  13. 13. Testing SOAP • Use mocks • Mocha: http://mocha.rubyforge.org
  14. 14. Testing SOAP def test_get_user_should_hit_client email = 'chrisw@nstrath.com' Outbound.client.expects(:getUser).with(email, Outbound.brand) Outbound.get_user(email) end
  15. 15. Testing SOAP soap_methods = { :getUser => true, :updateUser => true } Outbound.stubs(:client).returns(mock('SOAP Service', soap_methods))
  16. 16. Running a SOAP Server in Ruby
  17. 17. Just Kidding
  18. 18. Microformats! • Your website is your API • Plant classes in HTML • Tell parsers what information is important • http://microformats.org
  19. 19. hReview
  20. 20. hReview <div id="review_16873" class="hreview"> <h5 class="item"><span class="fn">Beringer California Collection White Merlot 20 <abbr class="dtreviewed" title="20070420">(1 day ago)</abbr> <span class="reviewer vcard"> <img class="photo" src="/assets/avatars/c19d1b2080f73765d420b461d3133ffa.jpg" <a class="url fn" href="/people/garyvaynerchuk">garyvaynerchuk</a> </span> <abbr class="rating" title="50.0">50.0<em>/100</em></abbr> <blockquote class="description">Had this in an industry event the other day, man <p class="tags">Tasting Tags: <a href="/tags/pink" rel="tag" class="rel-tag" title="view all wines with this t <a href="/tags/sugar" rel="tag" class="rel-tag" title="view all wines with this </p> </div>
  21. 21. hReview <div id="review_16873" class="hreview"> <h5 class="item"><span class="fn">Beringer California Collection White Merlot 20 <abbr class="dtreviewed" title="20070420">(1 day ago)</abbr> <span class="reviewer vcard"> <img class="photo" src="/assets/avatars/c19d1b2080f73765d420b461d3133ffa.jpg" <a class="url fn" href="/people/garyvaynerchuk">garyvaynerchuk</a> </span> <abbr class="rating" title="50.0">50.0<em>/100</em></abbr> <blockquote class="description">Had this in an industry event the other day, man <p class="tags">Tasting Tags: <a href="/tags/pink" rel="tag" class="rel-tag" title="view all wines with this t <a href="/tags/sugar" rel="tag" class="rel-tag" title="view all wines with this </p> </div>
  22. 22. mofo $ sudo gem install mofo Successfully installed mofo-0.2.2 $ irb -rubygems >> require 'mofo/hreview' => true >> review = HReview.find :first => 'http://corkd.com/wine/view/21670' => #<HReview:0x1598d04 ...> >> review.properties => ["description", "item", "dtreviewed", "tags", "rating", "reviewer"] >> review.rating => 50.0 >> review.item.fn => "Beringer California Collection White Merlot 2005" >> review.reviewer.fn => "garyvaynerchuk"
  23. 23. mofo/hreview.rb class HReview < Microformat one :version, :summary, :type, :dtreviewed, :rating, :description one :reviewer => HCard one :item! do one :fn end end
  24. 24. microformat.rb def collector collector = Hash.new([]) def collector.method_missing(method, *classes) super unless %w(one many).include? method.to_s self[method] += Microformat.send(:break_out_hashes, classes) end collector end
  25. 25. mofo supports... • xoxo • hCard • geo • hCalendar • adr • hReview • xfn • hEntry • hResume
  26. 26. What else can they do?
  27. 27. Operator
  28. 28. Operator
  29. 29. Okay.
  30. 30. Hpricot ( by _why )
  31. 31. Hpricot $ irb -rubygems -r'open-uri' >> require 'hpricot' => true >> page = Hpricot open('http://google.com') => #<Hpricot::Doc ...> >> page.search(:a).size => 20 >> page.at(:a) => {elem <a href="/url?sa=p&pref=ig&pval=3 &q=http://www.google.com/ig%3Fhl%3Den&usg= AFrqEzfPu3dYlSVsfjI7gUHePgEkcx_VXg"> "Personalize this page" </a>}
  32. 32. Hpricot Can use XPATH, CSS selectors, whatever, to search
  33. 33. Hpricot >> page = Hpricot(open('http://brainspl.at')) => #<Hpricot::Doc ...> >> page.search('.post').size => 10
  34. 34. Hpricot >> corkd = 'http://corkd.com/wine/view/21670' => 'http://corkd.com/wine/view/21670' >> page = Hpricot(open(corkd)) => #<Hpricot::Doc ...> >> page.search('.hreview').size => 4
  35. 35. Hpricot/:mofo >> page.at('.hreview').at('.item').at('.fn').inner_text => "Beringer California Collection White Merlot 2005" >> review.item.fn => "Beringer California Collection White Merlot 2005"
  36. 36. Oh, you can use Hpricot for XML, too. <Export> <Product> <SKU>403276</SKU> <ItemName>Trivet</ItemName> <CollectionNo>0</CollectionNo> <Pages>0</Pages> </Product> </Export>
  37. 37. Oh, you can use Hpricot for XML, too. fields = %w(SKU ItemName CollectionNo Pages) doc = Hpricot(open("my.xml")) (doc/:product).each do |xml_product| attributes = fields.inject({}) do |hash, field| hash.merge(field => xml_product.at(field).innerHTML) end Product.create(attributes) end ( also there’s Hpricot::XML() )
  38. 38. But who uses XML?
  39. 39. Cheat! http://cheat.errtheblog.com (insert short, live demo here)
  40. 40. Thanks • http://mofo.rubyforge.org • http://code.whytheluckystiff.net/hpricot • https://addons.mozilla.org/en-US/firefox/addon/4106 • http://microformats.org • http://upcoming.yahoo.com/ • http://corkd.com/ • http://chow.com • http://chowhound.com
  41. 41. Thanks • http://ronrothman.com/gallery/cnet/cnet_neon • http://flickr.com/photos/bootbearwdc/466751240/ • http://flickr.com/photos/segana/320699460/ • http://flickr.com/photos/spiffariffic/456211526/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×