SlideShare a Scribd company logo
1 of 45
Download to read offline
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 Ruby types to SOAP
  definitions
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
Why use SOAP?


• One reason: legacy.
Making and Breaking Web Services with Ruby
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)
end




def get_user(email)
  client.getUser(email, brand)
end
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
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
Making and Breaking Web Services with Ruby
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(email, Outbound.brand)
  Outbound.get_user(email)
end
Testing SOAP

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

Outbound.stubs(:client).returns(mock('SOAP Service', soap_methods))
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://microformats.org
hReview
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>
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>
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"
mofo/hreview.rb
class HReview < Microformat
  one :version, :summary, :type, :dtreviewed,
      :rating, :description

 one :reviewer => HCard

  one :item! do
    one :fn
  end
end
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
mofo supports...

              • xoxo
• hCard
              • geo
• hCalendar
              • adr
• hReview
              • xfn
• hEntry
• hResume
Making and Breaking Web Services with Ruby
Making and Breaking Web Services with Ruby
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::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>}
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(corkd))
=>   #<Hpricot::Doc ...>
>>   page.search('.hreview').size
=>   4
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"
Oh, you can use Hpricot
     for XML, too.
  <Export>
    <Product>
      <SKU>403276</SKU>
      <ItemName>Trivet</ItemName>
      <CollectionNo>0</CollectionNo>
      <Pages>0</Pages>
    </Product>
  </Export>
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() )
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/firefox/addon/4106

•   http://microformats.org

•   http://upcoming.yahoo.com/

•   http://corkd.com/

•   http://chow.com

•   http://chowhound.com
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/

More Related Content

What's hot

Action Controller Overview, Season 2
Action Controller Overview, Season 2Action Controller Overview, Season 2
Action Controller Overview, Season 2RORLAB
 
Even Faster Web Sites at The Ajax Experience
Even Faster Web Sites at The Ajax ExperienceEven Faster Web Sites at The Ajax Experience
Even Faster Web Sites at The Ajax ExperienceSteve Souders
 
RubyMotion
RubyMotionRubyMotion
RubyMotionMark
 
Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2RORLAB
 
Damage Control
Damage ControlDamage Control
Damage Controlsintaxi
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014Guillaume POTIER
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101Nando Vieira
 
Compatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsCompatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsKai Cui
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsMichelangelo van Dam
 
Turn your spaghetti code into ravioli with JavaScript modules
Turn your spaghetti code into ravioli with JavaScript modulesTurn your spaghetti code into ravioli with JavaScript modules
Turn your spaghetti code into ravioli with JavaScript modulesjerryorr
 
20111030i phonedeveloperworkshoppublished
20111030i phonedeveloperworkshoppublished20111030i phonedeveloperworkshoppublished
20111030i phonedeveloperworkshoppublishedYoichiro Sakurai
 
javascript for backend developers
javascript for backend developersjavascript for backend developers
javascript for backend developersThéodore Biadala
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsMike Subelsky
 
Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2RORLAB
 
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 

What's hot (20)

Excellent
ExcellentExcellent
Excellent
 
Action Controller Overview, Season 2
Action Controller Overview, Season 2Action Controller Overview, Season 2
Action Controller Overview, Season 2
 
RSpec
RSpecRSpec
RSpec
 
Even Faster Web Sites at The Ajax Experience
Even Faster Web Sites at The Ajax ExperienceEven Faster Web Sites at The Ajax Experience
Even Faster Web Sites at The Ajax Experience
 
RubyMotion
RubyMotionRubyMotion
RubyMotion
 
Rails is not just Ruby
Rails is not just RubyRails is not just Ruby
Rails is not just Ruby
 
Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2Action View Form Helpers - 1, Season 2
Action View Form Helpers - 1, Season 2
 
Damage Control
Damage ControlDamage Control
Damage Control
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 
How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014How to test complex SaaS applications - The family july 2014
How to test complex SaaS applications - The family july 2014
 
Metaprogramming 101
Metaprogramming 101Metaprogramming 101
Metaprogramming 101
 
Compatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensionsCompatibility Detector Tool of Chrome extensions
Compatibility Detector Tool of Chrome extensions
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
Turn your spaghetti code into ravioli with JavaScript modules
Turn your spaghetti code into ravioli with JavaScript modulesTurn your spaghetti code into ravioli with JavaScript modules
Turn your spaghetti code into ravioli with JavaScript modules
 
20111030i phonedeveloperworkshoppublished
20111030i phonedeveloperworkshoppublished20111030i phonedeveloperworkshoppublished
20111030i phonedeveloperworkshoppublished
 
javascript for backend developers
javascript for backend developersjavascript for backend developers
javascript for backend developers
 
Django tricks (2)
Django tricks (2)Django tricks (2)
Django tricks (2)
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2Layouts and Rendering in Rails, Season 2
Layouts and Rendering in Rails, Season 2
 
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and JasmineRails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
 

Similar to Making and Breaking Web Services with Ruby

Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 
Intro to-rails-webperf
Intro to-rails-webperfIntro to-rails-webperf
Intro to-rails-webperfNew Relic
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)True-Vision
 
Ruby MVC from scratch with Rack
Ruby MVC from scratch with RackRuby MVC from scratch with Rack
Ruby MVC from scratch with RackDonSchado
 
When To Use Ruby On Rails
When To Use Ruby On RailsWhen To Use Ruby On Rails
When To Use Ruby On Railsdosire
 
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyConsegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyFabio Akita
 
Building Scalable Websites with Perl
Building Scalable Websites with PerlBuilding Scalable Websites with Perl
Building Scalable Websites with PerlPerrin Harkins
 
Perl web app 테스트전략
Perl web app 테스트전략Perl web app 테스트전략
Perl web app 테스트전략Jeen Lee
 
Ruby on Rails in UbiSunrise
Ruby on Rails in UbiSunriseRuby on Rails in UbiSunrise
Ruby on Rails in UbiSunriseWisely chen
 
Server side scripting smack down - Node.js vs PHP
Server side scripting smack down - Node.js vs PHPServer side scripting smack down - Node.js vs PHP
Server side scripting smack down - Node.js vs PHPMarc Gear
 
WebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan WintermeyerWebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan WintermeyerElixir Club
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialYi-Ting Cheng
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发shaokun
 
performance vamos dormir mais?
performance vamos dormir mais?performance vamos dormir mais?
performance vamos dormir mais?tdc-globalcode
 
Michelin Starred Cooking with Chef
Michelin Starred Cooking with ChefMichelin Starred Cooking with Chef
Michelin Starred Cooking with ChefJon Cowie
 
Integration Test Cucumber + Webrat + Selenium
Integration Test Cucumber + Webrat + SeleniumIntegration Test Cucumber + Webrat + Selenium
Integration Test Cucumber + Webrat + Seleniumtka
 

Similar to Making and Breaking Web Services with Ruby (20)

Rails Performance
Rails PerformanceRails Performance
Rails Performance
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
Intro to-rails-webperf
Intro to-rails-webperfIntro to-rails-webperf
Intro to-rails-webperf
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)
 
Ruby MVC from scratch with Rack
Ruby MVC from scratch with RackRuby MVC from scratch with Rack
Ruby MVC from scratch with Rack
 
When To Use Ruby On Rails
When To Use Ruby On RailsWhen To Use Ruby On Rails
When To Use Ruby On Rails
 
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyConsegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
 
Building Scalable Websites with Perl
Building Scalable Websites with PerlBuilding Scalable Websites with Perl
Building Scalable Websites with Perl
 
Perl web app 테스트전략
Perl web app 테스트전략Perl web app 테스트전략
Perl web app 테스트전략
 
Ruby on Rails in UbiSunrise
Ruby on Rails in UbiSunriseRuby on Rails in UbiSunrise
Ruby on Rails in UbiSunrise
 
Server side scripting smack down - Node.js vs PHP
Server side scripting smack down - Node.js vs PHPServer side scripting smack down - Node.js vs PHP
Server side scripting smack down - Node.js vs PHP
 
WebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan WintermeyerWebPerformance: Why and How? – Stefan Wintermeyer
WebPerformance: Why and How? – Stefan Wintermeyer
 
OSDC 2009 Rails Turtorial
OSDC 2009 Rails TurtorialOSDC 2009 Rails Turtorial
OSDC 2009 Rails Turtorial
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发
 
performance vamos dormir mais?
performance vamos dormir mais?performance vamos dormir mais?
performance vamos dormir mais?
 
Rails 4.0
Rails 4.0Rails 4.0
Rails 4.0
 
Michelin Starred Cooking with Chef
Michelin Starred Cooking with ChefMichelin Starred Cooking with Chef
Michelin Starred Cooking with Chef
 
ApacheCon 2005
ApacheCon 2005ApacheCon 2005
ApacheCon 2005
 
Integration Test Cucumber + Webrat + Selenium
Integration Test Cucumber + Webrat + SeleniumIntegration Test Cucumber + Webrat + Selenium
Integration Test Cucumber + Webrat + Selenium
 

More from err

Inside GitHub
Inside GitHubInside GitHub
Inside GitHuberr
 
The Real-Time Web (and Other Buzzwords)
The Real-Time Web (and Other Buzzwords)The Real-Time Web (and Other Buzzwords)
The Real-Time Web (and Other Buzzwords)err
 
Git: The Lean, Mean, Distributed Machine
Git: The Lean, Mean, Distributed MachineGit: The Lean, Mean, Distributed Machine
Git: The Lean, Mean, Distributed Machineerr
 
Kings of Code 2009
Kings of Code 2009Kings of Code 2009
Kings of Code 2009err
 
Forbidden Fruit: A Taste of Ruby's ParseTree
Forbidden Fruit: A Taste of Ruby's ParseTreeForbidden Fruit: A Taste of Ruby's ParseTree
Forbidden Fruit: A Taste of Ruby's ParseTreeerr
 
Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)err
 
Kickin' Ass with Cache-Fu (with notes)
Kickin' Ass with Cache-Fu (with notes)Kickin' Ass with Cache-Fu (with notes)
Kickin' Ass with Cache-Fu (with notes)err
 

More from err (7)

Inside GitHub
Inside GitHubInside GitHub
Inside GitHub
 
The Real-Time Web (and Other Buzzwords)
The Real-Time Web (and Other Buzzwords)The Real-Time Web (and Other Buzzwords)
The Real-Time Web (and Other Buzzwords)
 
Git: The Lean, Mean, Distributed Machine
Git: The Lean, Mean, Distributed MachineGit: The Lean, Mean, Distributed Machine
Git: The Lean, Mean, Distributed Machine
 
Kings of Code 2009
Kings of Code 2009Kings of Code 2009
Kings of Code 2009
 
Forbidden Fruit: A Taste of Ruby's ParseTree
Forbidden Fruit: A Taste of Ruby's ParseTreeForbidden Fruit: A Taste of Ruby's ParseTree
Forbidden Fruit: A Taste of Ruby's ParseTree
 
Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)Kickin' Ass with Cache-Fu (without notes)
Kickin' Ass with Cache-Fu (without notes)
 
Kickin' Ass with Cache-Fu (with notes)
Kickin' Ass with Cache-Fu (with notes)Kickin' Ass with Cache-Fu (with notes)
Kickin' Ass with Cache-Fu (with notes)
 

Recently uploaded

ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...
ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...
ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...ISONIKELtd
 
IIBA® Melbourne - Navigating Business Analysis - Excellence for Career Growth...
IIBA® Melbourne - Navigating Business Analysis - Excellence for Career Growth...IIBA® Melbourne - Navigating Business Analysis - Excellence for Career Growth...
IIBA® Melbourne - Navigating Business Analysis - Excellence for Career Growth...AustraliaChapterIIBA
 
Anyhr.io | Presentation HR&Recruiting agency
Anyhr.io | Presentation HR&Recruiting agencyAnyhr.io | Presentation HR&Recruiting agency
Anyhr.io | Presentation HR&Recruiting agencyHanna Klim
 
Entrepreneurship & organisations: influences and organizations
Entrepreneurship & organisations: influences and organizationsEntrepreneurship & organisations: influences and organizations
Entrepreneurship & organisations: influences and organizationsP&CO
 
Live-Streaming in the Music Industry Webinar
Live-Streaming in the Music Industry WebinarLive-Streaming in the Music Industry Webinar
Live-Streaming in the Music Industry WebinarNathanielSchmuck
 
PDT 88 - 4 million seed - Seed - Protecto.pdf
PDT 88 - 4 million seed - Seed - Protecto.pdfPDT 88 - 4 million seed - Seed - Protecto.pdf
PDT 88 - 4 million seed - Seed - Protecto.pdfHajeJanKamps
 
Introduction to The overview of GAAP LO 1-5.pptx
Introduction to The overview of GAAP LO 1-5.pptxIntroduction to The overview of GAAP LO 1-5.pptx
Introduction to The overview of GAAP LO 1-5.pptxJemalSeid25
 
Amazon ppt.pptx Amazon about the company
Amazon ppt.pptx Amazon about the companyAmazon ppt.pptx Amazon about the company
Amazon ppt.pptx Amazon about the companyfashionfound007
 
UNLEASHING THE POWER OF PROGRAMMATIC ADVERTISING
UNLEASHING THE POWER OF PROGRAMMATIC ADVERTISINGUNLEASHING THE POWER OF PROGRAMMATIC ADVERTISING
UNLEASHING THE POWER OF PROGRAMMATIC ADVERTISINGlokeshwarmaha
 
Ethical stalking by Mark Williams. UpliftLive 2024
Ethical stalking by Mark Williams. UpliftLive 2024Ethical stalking by Mark Williams. UpliftLive 2024
Ethical stalking by Mark Williams. UpliftLive 2024Winbusinessin
 
MC Heights construction company in Jhang
MC Heights construction company in JhangMC Heights construction company in Jhang
MC Heights construction company in Jhangmcgroupjeya
 
Talent Management research intelligence_13 paradigm shifts_20 March 2024.pdf
Talent Management research intelligence_13 paradigm shifts_20 March 2024.pdfTalent Management research intelligence_13 paradigm shifts_20 March 2024.pdf
Talent Management research intelligence_13 paradigm shifts_20 March 2024.pdfCharles Cotter, PhD
 
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptx
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptxHELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptx
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptxHelene Heckrotte
 
Team B Mind Map for Organizational Chg..
Team B Mind Map for Organizational Chg..Team B Mind Map for Organizational Chg..
Team B Mind Map for Organizational Chg..dlewis191
 
Personal Brand Exploration Presentation Eric Bonilla
Personal Brand Exploration Presentation Eric BonillaPersonal Brand Exploration Presentation Eric Bonilla
Personal Brand Exploration Presentation Eric BonillaEricBonilla13
 
Upgrade Your Banking Experience with Advanced Core Banking Applications
Upgrade Your Banking Experience with Advanced Core Banking ApplicationsUpgrade Your Banking Experience with Advanced Core Banking Applications
Upgrade Your Banking Experience with Advanced Core Banking ApplicationsIntellect Design Arena Ltd
 
A flour, rice and Suji company in Jhang.
A flour, rice and Suji company in Jhang.A flour, rice and Suji company in Jhang.
A flour, rice and Suji company in Jhang.mcshagufta46
 
Trauma Training Service for First Responders
Trauma Training Service for First RespondersTrauma Training Service for First Responders
Trauma Training Service for First RespondersBPOQe
 
Borderless Access - Global B2B Panel book-unlock 2024
Borderless Access - Global B2B Panel book-unlock 2024Borderless Access - Global B2B Panel book-unlock 2024
Borderless Access - Global B2B Panel book-unlock 2024Borderless Access
 

Recently uploaded (20)

ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...
ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...
ISONIKE Ltd Accreditation for the Conformity Assessment and Certification of ...
 
IIBA® Melbourne - Navigating Business Analysis - Excellence for Career Growth...
IIBA® Melbourne - Navigating Business Analysis - Excellence for Career Growth...IIBA® Melbourne - Navigating Business Analysis - Excellence for Career Growth...
IIBA® Melbourne - Navigating Business Analysis - Excellence for Career Growth...
 
Anyhr.io | Presentation HR&Recruiting agency
Anyhr.io | Presentation HR&Recruiting agencyAnyhr.io | Presentation HR&Recruiting agency
Anyhr.io | Presentation HR&Recruiting agency
 
Entrepreneurship & organisations: influences and organizations
Entrepreneurship & organisations: influences and organizationsEntrepreneurship & organisations: influences and organizations
Entrepreneurship & organisations: influences and organizations
 
Live-Streaming in the Music Industry Webinar
Live-Streaming in the Music Industry WebinarLive-Streaming in the Music Industry Webinar
Live-Streaming in the Music Industry Webinar
 
PDT 88 - 4 million seed - Seed - Protecto.pdf
PDT 88 - 4 million seed - Seed - Protecto.pdfPDT 88 - 4 million seed - Seed - Protecto.pdf
PDT 88 - 4 million seed - Seed - Protecto.pdf
 
Introduction to The overview of GAAP LO 1-5.pptx
Introduction to The overview of GAAP LO 1-5.pptxIntroduction to The overview of GAAP LO 1-5.pptx
Introduction to The overview of GAAP LO 1-5.pptx
 
Amazon ppt.pptx Amazon about the company
Amazon ppt.pptx Amazon about the companyAmazon ppt.pptx Amazon about the company
Amazon ppt.pptx Amazon about the company
 
UNLEASHING THE POWER OF PROGRAMMATIC ADVERTISING
UNLEASHING THE POWER OF PROGRAMMATIC ADVERTISINGUNLEASHING THE POWER OF PROGRAMMATIC ADVERTISING
UNLEASHING THE POWER OF PROGRAMMATIC ADVERTISING
 
Ethical stalking by Mark Williams. UpliftLive 2024
Ethical stalking by Mark Williams. UpliftLive 2024Ethical stalking by Mark Williams. UpliftLive 2024
Ethical stalking by Mark Williams. UpliftLive 2024
 
MC Heights construction company in Jhang
MC Heights construction company in JhangMC Heights construction company in Jhang
MC Heights construction company in Jhang
 
Talent Management research intelligence_13 paradigm shifts_20 March 2024.pdf
Talent Management research intelligence_13 paradigm shifts_20 March 2024.pdfTalent Management research intelligence_13 paradigm shifts_20 March 2024.pdf
Talent Management research intelligence_13 paradigm shifts_20 March 2024.pdf
 
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptx
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptxHELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptx
HELENE HECKROTTE'S PROFESSIONAL PORTFOLIO.pptx
 
Team B Mind Map for Organizational Chg..
Team B Mind Map for Organizational Chg..Team B Mind Map for Organizational Chg..
Team B Mind Map for Organizational Chg..
 
Personal Brand Exploration Presentation Eric Bonilla
Personal Brand Exploration Presentation Eric BonillaPersonal Brand Exploration Presentation Eric Bonilla
Personal Brand Exploration Presentation Eric Bonilla
 
Upgrade Your Banking Experience with Advanced Core Banking Applications
Upgrade Your Banking Experience with Advanced Core Banking ApplicationsUpgrade Your Banking Experience with Advanced Core Banking Applications
Upgrade Your Banking Experience with Advanced Core Banking Applications
 
A flour, rice and Suji company in Jhang.
A flour, rice and Suji company in Jhang.A flour, rice and Suji company in Jhang.
A flour, rice and Suji company in Jhang.
 
Trauma Training Service for First Responders
Trauma Training Service for First RespondersTrauma Training Service for First Responders
Trauma Training Service for First Responders
 
WAM Corporate Presentation Mar 25 2024.pdf
WAM Corporate Presentation Mar 25 2024.pdfWAM Corporate Presentation Mar 25 2024.pdf
WAM Corporate Presentation Mar 25 2024.pdf
 
Borderless Access - Global B2B Panel book-unlock 2024
Borderless Access - Global B2B Panel book-unlock 2024Borderless Access - Global B2B Panel book-unlock 2024
Borderless Access - Global B2B Panel book-unlock 2024
 

Making and Breaking Web Services with Ruby

  • 1. Making and Breaking Web Services (with Ruby) Chris Wanstrath Err Free http://errfree.com
  • 3. SOAP • Simple Object Access Protocol? • Lies. • Service Oriented Architecture Protocol • wtf.
  • 5. “Outbound” • Slow response time • Duplication of data • Hard to debug • require ‘soap/wsdlDriver’
  • 6. Ruby SOAP Library: Your Friend • Creates methods on the fly • Seems to work pretty well • Transparently converts Ruby types to SOAP definitions
  • 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. Why use SOAP? • One reason: legacy.
  • 10. Wrapping SOAP def update_user(email, subs = [], unsubs = []) client.updateUser(brand, email, email, demo, subs, unsubs) end
  • 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. 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. 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
  • 15. Testing SOAP • Use mocks • Mocha: http://mocha.rubyforge.org
  • 16. 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
  • 17. Testing SOAP soap_methods = { :getUser => true, :updateUser => true } Outbound.stubs(:client).returns(mock('SOAP Service', soap_methods))
  • 18. Running a SOAP Server in Ruby
  • 20. Microformats! • Your website is your API • Plant classes in HTML • Tell parsers what information is important • http://microformats.org
  • 22. 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>
  • 23. 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>
  • 24. 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"
  • 25. mofo/hreview.rb class HReview < Microformat one :version, :summary, :type, :dtreviewed, :rating, :description one :reviewer => HCard one :item! do one :fn end end
  • 26. 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
  • 27. mofo supports... • xoxo • hCard • geo • hCalendar • adr • hReview • xfn • hEntry • hResume
  • 30. What else can they do?
  • 33. Okay.
  • 35. 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>}
  • 36. Hpricot Can use XPATH, CSS selectors, whatever, to search
  • 37. Hpricot >> page = Hpricot(open('http://brainspl.at')) => #<Hpricot::Doc ...> >> page.search('.post').size => 10
  • 38. 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
  • 39. 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"
  • 40. Oh, you can use Hpricot for XML, too. <Export> <Product> <SKU>403276</SKU> <ItemName>Trivet</ItemName> <CollectionNo>0</CollectionNo> <Pages>0</Pages> </Product> </Export>
  • 41. 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() )
  • 43. Cheat! http://cheat.errtheblog.com (insert short, live demo here)
  • 44. 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
  • 45. 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/