SlideShare a Scribd company logo
Sinatra, Testing in Sinatra, Redis
   Vassilis Vatikiotis, Athens Ruby Meetup 7
Sinatra
   Web micro framework and DSL.
   > 4000 LOC, 6 Classes. Study!
   Modular & standalone style.
   Small apps & web services. 
   Rack compatible.
   Extendible.
   Very popular: 182 gems in rubygems.org
   MRI & 1.9, Rubinius 1.2.3, Jruby 1.6 full support. 
            MacRuby, IronRuby (reported OK).
Hello world

require 'sinatra'

get '/' do
  'Hello world!'
end


Can't beat that!
Sinatra basics (1.2.6)
   Route matching: HTTP method + URL pattern.
           Strings, regexps. Conditions allowed.
            get '/say/:what/to/*', :host_name => /^admin./ do
              params[:what]
              what = #{what}
              params[:splat] # => Array
              erb :index
            end

   Views and Templates.
           ERB, Haml, Builder, Nokogiri, Sass, Markdown, 
             Coffescript and more.
           Embedded, inline, file.
Sinatra basics
   Filters
           Before and after filters.
           URL patterns and conditions (just like routes).
   Helpers support a host of tools:
           Sessions.
           Request “flow” control: halt, pass, trigger route.
           Set HTTP headers, status, body, mime type.
           .configure to set things to run once.
           Examine request, logging.
   Error handlers look like routes.
Sinatra – scope/binding
   Everything inherits from Sinatra::Base
   Request object accessible within route blocks, helper 
      methods, filters, views, own methods.
   Single application class for all requests; you cannot access 
      request or session at class level.
   Application scope accessible within: 
           settings.get within request scope.
           class body & block to helper method.
           blocks/procs used as value in set
           block to Sinatra.new
Sinatra and Rack stack
   Sits on top of Rack.
             middleware pipelines via Sinatra::Base.use
   Modular and Classic style.
             Classic Sinatra::Application pollutes global namespace.
             Modular Sinatra::Base ­ we can build a stack e.g. more 
               sinatra, padrino, ramaze, rails, any rack abiding citizen
   We can dynamically create a Sinatra app...
    + (Object) Sinatra.new(base = Base, options = {}, &block)

   ...and use it somewhere in the stack!
    use Sinatra { get('/') { ... } }

    run My::EndPoint
Shamelessly ripped example
require 'sinatra/base'

class LoginScreen < Sinatra::Base
  enable :sessions
  set :session_secret, 'super secret'

 get('/login') { haml :login }

  post('/login') do
    if params[:name] == 'admin' && params[:password] == 'admin'
      session['user_name'] = params[:name]
    else
      redirect '/login'
    end
  end
end

class MyApp < Sinatra::Base
  use LoginScreen

 before do
   unless session['user_name']
     halt "Access denied, please <a href='/login'>login</a>."
   end
 end

  get('/') { "Hello #{session['user_name']}." }
end
Extending Sinatra
   Instance context: using helpers method
    module Sinatra
      module HTMLEscapeHelper
        def h(text)
          Rack::Utils.escape_html(text)
        end
      end
      helpers HTMLEscapeHelper
    end
   Class context: using register method
    module Sinatra
      module LinkBlocker
        def block_links_from(host)
          before {
             halt 403, "Go Away!" if request.referer.match(host) }
        end
      end
      register LinkBlocker
    end
Testing in Sinatra
   Use generic test frameworks – mix in Rack::Test::Methods. 
     require 'rack/test' Check source! 
   Webrat / Capybara require minimal wiring.
   Use last_response object, query everything you want.
    it "says hello" do
      get '/hello'
      response = JSON.parse(last_response.body)
      response["ProxyResponse"].should == @page_id
      last_response.should be_ok
    end
    it "says hello" do
      visit '/hello'
      page.should have_content('hello_world')
    end
Sinatra & testing
   Sinatra is excellent for implementing web services.
           Lean framework.
           Views? I don't need views.
           Rack middleware in place.
   Sinatra/WS is excellent for getting comfy with testing.
           Integration testing is easy; exercise and verify!
           You are doing state verification.
           Don't get confused with behavior verification 
             (Rspec?)
   Want to grok testing? Code a Sinatra web service.
Intermission I
            Bite the bullet: Test it!
   Beginnings are hard! Grok testing, figure out the api(s), 
      figure out which api(s), figure out when... go figure!
   Test cycle: setup, exercise, verify, teardown.
   Exercise SUT, use doubles for collaboration.
   Test Double is a generic term for a test obj.
           A stub provides a canned answer.
           A mock “is a stub” which enforces behavior checks.
   Classic TDD vs Mockist TDD vs BDD.
Intermission II
                     Stub example
    Project.stub(:find).and_return( Project.new(
      :name => “Greek reboot”))

    stub_project = Project.find(1)
    previous_count = manager.projects.count

    manager.projects << stub_project
    manager.projects.count.should == previous_count + 1

   SUT is the manager object.
   A stub is a collaborator used to help testing the SUT.
Intermission III
                 Mock example
post '/manager/:role' do
    manager.switch_role params[:role]
end

class Manager
  attr_accessor :role
  def switch_role( role )
    @role = (role == 'team leader' ? 'project leader' : 'team
leader')
  end
end

#this is my test
it “/manager/role spews back the role” do
  mock_manager = Manager.new( :role => 'team leader' )
  mock_manager.should_receive(:switch_role).and_return('project
leader')
  post '/manager/:role', mock_manager

  last_response.body.should == 'project leader'
end
Steps
   Sinatra and HTTP services is ideal for getting you started 
      with testing.
   Write a small sinatra app, no views, think in term of HTTP 
     endpoints.
   REST is not required!
   Integration test it. Minimal api knowledge. Want to try 
      stubs? stub a :find ­ user maybe?
   Now do it backwards. Write tests first!
   I'm severely TDDing!
JSON Query HTTP Service
                Goal
   Service provides data in json format.
   I need a portion of a map.
   I need just a portion of a big data chunk.
   I want to be able to query for my bits of data.
   Ideally I want the data service to provide me with such a 
      facility.
   JSON Query Service deals with the above.
JSON Query HTTP Service
               Issues
   JSON selector as a service.
   JSONSelect, JSONPath, XPATH.
   Issue: there is no established json selector mechanism.
           Work around it or use non established methods,
           own implementation.
   Need to fetch and cache the requested source.
   Issue: cache component need to scale out and be consistent.
   Issue: potentially massive service load.
JSON Query HTTP Service
              Frontend
   Sinatra.
   No RESTful API. Do not need one (atm).
   Request a portion of a json page.
   Response is the requested json portion, with metadata. All 
      wrapped in a json response.
   Works for multiple URLs.
JSON Query HTTP Service
              Backend
   Redis. key­value data store, can be used as cache.
   Fast! compared with memcached? YMMV.
   Clustering? Not here yet!
   Used it as a concept. Selling point? Virtual Memory
           What if we run out of memory?
           suitable for large values, keys are requested URLs
   Keys in memory, values on disk.
   Idea: SSD for memory, slower disk for values.
How can I use it?
require 'net/http'
require 'json'

post_data = {
     :apikey => "dc25ece96592813032f3605e95e8c6e9669cad46",
     :guid => "123123",
     :xpath => "//leg[2], //leg[1]",
     :url => "http://maps.googleapis.com/maps/api/directions/json?
origin=Chicago,IL&destination=Los+Angeles,CA&waypoints=Joplin,MO|
Oklahoma+City,OK&sensor=false”
}

document =
Net::HTTP.post_form( URI.parse('http://jsonquery.heroku.com/v1/fetch_page') ,
post_data )

response = JSON.parse( document.body )
xpath_1 = response["ProxyResponse"]["url_1"]["xpath_1"][“response”]
xpath_2 = response["ProxyResponse"]["url_1"]["xpath_2"][“response”]
Future
   XML support.
   Redis VM support is dropped in 2.4
           Need to investigate memcache, membase, riak and so 
             on. Many solutions according to domain.
   Scale. How?
           Usual approach so far is to spawn multiple processes.
           Threaded vs Evented.
           Unicorn, Mongrel, Thin, Rainbows, Passenger, 
             Zbattery, Goliath.
Bibliography

1) Mocks aren't Stubs. Martin Fowler
2) Service­oriented design with Ruby and Rails. Paul Dix et 
    al
3) The Rspec book, David Chelimsky et al
4) Rails test prescriptions, Noel Rappin
5) Sinatra and testing from a pro: Peepcode Play­by­Play 
    (episode 54) with J. Barnette 

More Related Content

What's hot

The Best (and Worst) of Django
The Best (and Worst) of DjangoThe Best (and Worst) of Django
The Best (and Worst) of DjangoJacob Kaplan-Moss
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for you
Simon Willison
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
Simon Willison
 
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 MinutesDjangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Nina Zakharenko
 
Create responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSCreate responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJS
Hannes Hapke
 
Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Jacob Kaplan-Moss
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
Eric Palakovich Carr
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012Maintainable JavaScript 2012
Maintainable JavaScript 2012
Nicholas Zakas
 
The effective use of Django ORM
The effective use of Django ORMThe effective use of Django ORM
The effective use of Django ORM
Yaroslav Muravskyi
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
Daniel Cukier
 
Presentation
PresentationPresentation
Presentation
Manav Prasad
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overview
jeresig
 
Polyglot payloads in practice by avlidienbrunn at HackPra
Polyglot payloads in practice by avlidienbrunn at HackPraPolyglot payloads in practice by avlidienbrunn at HackPra
Polyglot payloads in practice by avlidienbrunn at HackPra
Mathias Karlsson
 
JavaScript Basics with baby steps
JavaScript Basics with baby stepsJavaScript Basics with baby steps
JavaScript Basics with baby steps
Muhammad khurram khan
 
Django a whirlwind tour
Django   a whirlwind tourDjango   a whirlwind tour
Django a whirlwind tour
Brad Montgomery
 
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
CODE BLUE
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
fakedarren
 
Moving from Django Apps to Services
Moving from Django Apps to ServicesMoving from Django Apps to Services
Moving from Django Apps to Services
Craig Kerstiens
 
Two scoops of Django - Security Best Practices
Two scoops of Django - Security Best PracticesTwo scoops of Django - Security Best Practices
Two scoops of Django - Security Best Practices
Spin Lai
 

What's hot (20)

The Best (and Worst) of Django
The Best (and Worst) of DjangoThe Best (and Worst) of Django
The Best (and Worst) of Django
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for you
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 MinutesDjangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes
 
Create responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSCreate responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJS
 
Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012Maintainable JavaScript 2012
Maintainable JavaScript 2012
 
The effective use of Django ORM
The effective use of Django ORMThe effective use of Django ORM
The effective use of Django ORM
 
Jsp
JspJsp
Jsp
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Presentation
PresentationPresentation
Presentation
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overview
 
Polyglot payloads in practice by avlidienbrunn at HackPra
Polyglot payloads in practice by avlidienbrunn at HackPraPolyglot payloads in practice by avlidienbrunn at HackPra
Polyglot payloads in practice by avlidienbrunn at HackPra
 
JavaScript Basics with baby steps
JavaScript Basics with baby stepsJavaScript Basics with baby steps
JavaScript Basics with baby steps
 
Django a whirlwind tour
Django   a whirlwind tourDjango   a whirlwind tour
Django a whirlwind tour
 
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
XSS Attacks Exploiting XSS Filter by Masato Kinugawa - CODE BLUE 2015
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
 
Moving from Django Apps to Services
Moving from Django Apps to ServicesMoving from Django Apps to Services
Moving from Django Apps to Services
 
Two scoops of Django - Security Best Practices
Two scoops of Django - Security Best PracticesTwo scoops of Django - Security Best Practices
Two scoops of Django - Security Best Practices
 

Viewers also liked

Money, Sex and Evolution - Simulation and data analysis with Ruby and R
Money, Sex and Evolution - Simulation and data analysis with Ruby and RMoney, Sex and Evolution - Simulation and data analysis with Ruby and R
Money, Sex and Evolution - Simulation and data analysis with Ruby and R
Sau Sheong Chang
 
Ruby And The Cloud
Ruby And The CloudRuby And The Cloud
Ruby And The Cloud
Sau Sheong Chang
 
Swing when you're winning - an introduction to Ruby and Sinatra
Swing when you're winning - an introduction to Ruby and SinatraSwing when you're winning - an introduction to Ruby and Sinatra
Swing when you're winning - an introduction to Ruby and Sinatra
Matt Gifford
 
Ruby and R
Ruby and RRuby and R
Ruby and R
Sau Sheong Chang
 

Viewers also liked (7)

Acquisition management
Acquisition management Acquisition management
Acquisition management
 
Earned value analysis
Earned value analysisEarned value analysis
Earned value analysis
 
Money, Sex and Evolution - Simulation and data analysis with Ruby and R
Money, Sex and Evolution - Simulation and data analysis with Ruby and RMoney, Sex and Evolution - Simulation and data analysis with Ruby and R
Money, Sex and Evolution - Simulation and data analysis with Ruby and R
 
Ruby And The Cloud
Ruby And The CloudRuby And The Cloud
Ruby And The Cloud
 
Swing when you're winning - an introduction to Ruby and Sinatra
Swing when you're winning - an introduction to Ruby and SinatraSwing when you're winning - an introduction to Ruby and Sinatra
Swing when you're winning - an introduction to Ruby and Sinatra
 
Sinatra
SinatraSinatra
Sinatra
 
Ruby and R
Ruby and RRuby and R
Ruby and R
 

Similar to Sinatra and JSONQuery Web Service

Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
Emanuele DelBono
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
LaunchAny
 
JavaScript 2.0 in Dreamweaver CS4
JavaScript 2.0 in Dreamweaver CS4JavaScript 2.0 in Dreamweaver CS4
JavaScript 2.0 in Dreamweaver CS4
alexsaves
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Ruby on Rails: Coding Guideline
Ruby on Rails: Coding GuidelineRuby on Rails: Coding Guideline
Ruby on Rails: Coding Guideline
Nascenia IT
 
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
Mike Subelsky
 
Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1Mohammad Qureshi
 
Taming client-server communication
Taming client-server communicationTaming client-server communication
Taming client-server communicationscothis
 
1.6 米嘉 gobuildweb
1.6 米嘉 gobuildweb1.6 米嘉 gobuildweb
1.6 米嘉 gobuildweb
Leo Zhou
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
dwm042
 
Bettercap
BettercapBettercap
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
soft-shake.ch
 
Motion Django Meetup
Motion Django MeetupMotion Django Meetup
Motion Django Meetup
Mike Malone
 
Sherlock Homepage - A detective story about running large web services - WebN...
Sherlock Homepage - A detective story about running large web services - WebN...Sherlock Homepage - A detective story about running large web services - WebN...
Sherlock Homepage - A detective story about running large web services - WebN...
Maarten Balliauw
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.js
Chris Cowan
 
Sherlock Homepage - A detective story about running large web services (VISUG...
Sherlock Homepage - A detective story about running large web services (VISUG...Sherlock Homepage - A detective story about running large web services (VISUG...
Sherlock Homepage - A detective story about running large web services (VISUG...
Maarten Balliauw
 
Sherlock Homepage (Maarten Balliauw)
Sherlock Homepage (Maarten Balliauw)Sherlock Homepage (Maarten Balliauw)
Sherlock Homepage (Maarten Balliauw)
Visug
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Matt Raible
 
Dynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web siteDynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web site
Sriram Natarajan
 

Similar to Sinatra and JSONQuery Web Service (20)

Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
Using Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in RubyUsing Sinatra to Build REST APIs in Ruby
Using Sinatra to Build REST APIs in Ruby
 
JavaScript 2.0 in Dreamweaver CS4
JavaScript 2.0 in Dreamweaver CS4JavaScript 2.0 in Dreamweaver CS4
JavaScript 2.0 in Dreamweaver CS4
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Ruby on Rails: Coding Guideline
Ruby on Rails: Coding GuidelineRuby on Rails: Coding Guideline
Ruby on Rails: Coding Guideline
 
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
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
 
Taming client-server communication
Taming client-server communicationTaming client-server communication
Taming client-server communication
 
1.6 米嘉 gobuildweb
1.6 米嘉 gobuildweb1.6 米嘉 gobuildweb
1.6 米嘉 gobuildweb
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
 
Bettercap
BettercapBettercap
Bettercap
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
 
Motion Django Meetup
Motion Django MeetupMotion Django Meetup
Motion Django Meetup
 
Sherlock Homepage - A detective story about running large web services - WebN...
Sherlock Homepage - A detective story about running large web services - WebN...Sherlock Homepage - A detective story about running large web services - WebN...
Sherlock Homepage - A detective story about running large web services - WebN...
 
Intro To Node.js
Intro To Node.jsIntro To Node.js
Intro To Node.js
 
Sherlock Homepage - A detective story about running large web services (VISUG...
Sherlock Homepage - A detective story about running large web services (VISUG...Sherlock Homepage - A detective story about running large web services (VISUG...
Sherlock Homepage - A detective story about running large web services (VISUG...
 
Sherlock Homepage (Maarten Balliauw)
Sherlock Homepage (Maarten Balliauw)Sherlock Homepage (Maarten Balliauw)
Sherlock Homepage (Maarten Balliauw)
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
 
Dynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web siteDynamic Tracing of your AMP web site
Dynamic Tracing of your AMP web site
 

Recently uploaded

Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.
ViralQR
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
UiPathCommunity
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 

Recently uploaded (20)

Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.Welocme to ViralQR, your best QR code generator.
Welocme to ViralQR, your best QR code generator.
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 

Sinatra and JSONQuery Web Service

  • 1. Sinatra, Testing in Sinatra, Redis Vassilis Vatikiotis, Athens Ruby Meetup 7
  • 2. Sinatra  Web micro framework and DSL.  > 4000 LOC, 6 Classes. Study!  Modular & standalone style.  Small apps & web services.   Rack compatible.  Extendible.  Very popular: 182 gems in rubygems.org  MRI & 1.9, Rubinius 1.2.3, Jruby 1.6 full support.   MacRuby, IronRuby (reported OK).
  • 3. Hello world require 'sinatra' get '/' do 'Hello world!' end Can't beat that!
  • 4. Sinatra basics (1.2.6)  Route matching: HTTP method + URL pattern.  Strings, regexps. Conditions allowed. get '/say/:what/to/*', :host_name => /^admin./ do params[:what] what = #{what} params[:splat] # => Array erb :index end  Views and Templates.  ERB, Haml, Builder, Nokogiri, Sass, Markdown,  Coffescript and more.  Embedded, inline, file.
  • 5. Sinatra basics  Filters  Before and after filters.  URL patterns and conditions (just like routes).  Helpers support a host of tools:  Sessions.  Request “flow” control: halt, pass, trigger route.  Set HTTP headers, status, body, mime type.  .configure to set things to run once.  Examine request, logging.  Error handlers look like routes.
  • 6. Sinatra – scope/binding  Everything inherits from Sinatra::Base  Request object accessible within route blocks, helper  methods, filters, views, own methods.  Single application class for all requests; you cannot access  request or session at class level.  Application scope accessible within:   settings.get within request scope.  class body & block to helper method.  blocks/procs used as value in set  block to Sinatra.new
  • 7. Sinatra and Rack stack  Sits on top of Rack.  middleware pipelines via Sinatra::Base.use  Modular and Classic style.  Classic Sinatra::Application pollutes global namespace.  Modular Sinatra::Base ­ we can build a stack e.g. more  sinatra, padrino, ramaze, rails, any rack abiding citizen  We can dynamically create a Sinatra app... + (Object) Sinatra.new(base = Base, options = {}, &block)  ...and use it somewhere in the stack! use Sinatra { get('/') { ... } } run My::EndPoint
  • 8. Shamelessly ripped example require 'sinatra/base' class LoginScreen < Sinatra::Base enable :sessions set :session_secret, 'super secret' get('/login') { haml :login } post('/login') do if params[:name] == 'admin' && params[:password] == 'admin' session['user_name'] = params[:name] else redirect '/login' end end end class MyApp < Sinatra::Base use LoginScreen before do unless session['user_name'] halt "Access denied, please <a href='/login'>login</a>." end end get('/') { "Hello #{session['user_name']}." } end
  • 9. Extending Sinatra  Instance context: using helpers method module Sinatra module HTMLEscapeHelper def h(text) Rack::Utils.escape_html(text) end end helpers HTMLEscapeHelper end  Class context: using register method module Sinatra module LinkBlocker def block_links_from(host) before { halt 403, "Go Away!" if request.referer.match(host) } end end register LinkBlocker end
  • 10. Testing in Sinatra  Use generic test frameworks – mix in Rack::Test::Methods.  require 'rack/test' Check source!   Webrat / Capybara require minimal wiring.  Use last_response object, query everything you want. it "says hello" do get '/hello' response = JSON.parse(last_response.body) response["ProxyResponse"].should == @page_id last_response.should be_ok end it "says hello" do visit '/hello' page.should have_content('hello_world') end
  • 11. Sinatra & testing  Sinatra is excellent for implementing web services.  Lean framework.  Views? I don't need views.  Rack middleware in place.  Sinatra/WS is excellent for getting comfy with testing.  Integration testing is easy; exercise and verify!  You are doing state verification.  Don't get confused with behavior verification  (Rspec?)  Want to grok testing? Code a Sinatra web service.
  • 12. Intermission I Bite the bullet: Test it!  Beginnings are hard! Grok testing, figure out the api(s),  figure out which api(s), figure out when... go figure!  Test cycle: setup, exercise, verify, teardown.  Exercise SUT, use doubles for collaboration.  Test Double is a generic term for a test obj.  A stub provides a canned answer.  A mock “is a stub” which enforces behavior checks.  Classic TDD vs Mockist TDD vs BDD.
  • 13. Intermission II Stub example Project.stub(:find).and_return( Project.new( :name => “Greek reboot”)) stub_project = Project.find(1) previous_count = manager.projects.count manager.projects << stub_project manager.projects.count.should == previous_count + 1  SUT is the manager object.  A stub is a collaborator used to help testing the SUT.
  • 14. Intermission III Mock example post '/manager/:role' do manager.switch_role params[:role] end class Manager attr_accessor :role def switch_role( role ) @role = (role == 'team leader' ? 'project leader' : 'team leader') end end #this is my test it “/manager/role spews back the role” do mock_manager = Manager.new( :role => 'team leader' ) mock_manager.should_receive(:switch_role).and_return('project leader') post '/manager/:role', mock_manager last_response.body.should == 'project leader' end
  • 15. Steps  Sinatra and HTTP services is ideal for getting you started  with testing.  Write a small sinatra app, no views, think in term of HTTP  endpoints.  REST is not required!  Integration test it. Minimal api knowledge. Want to try  stubs? stub a :find ­ user maybe?  Now do it backwards. Write tests first!  I'm severely TDDing!
  • 16. JSON Query HTTP Service Goal  Service provides data in json format.  I need a portion of a map.  I need just a portion of a big data chunk.  I want to be able to query for my bits of data.  Ideally I want the data service to provide me with such a  facility.  JSON Query Service deals with the above.
  • 17. JSON Query HTTP Service Issues  JSON selector as a service.  JSONSelect, JSONPath, XPATH.  Issue: there is no established json selector mechanism.  Work around it or use non established methods,  own implementation.  Need to fetch and cache the requested source.  Issue: cache component need to scale out and be consistent.  Issue: potentially massive service load.
  • 18. JSON Query HTTP Service Frontend  Sinatra.  No RESTful API. Do not need one (atm).  Request a portion of a json page.  Response is the requested json portion, with metadata. All  wrapped in a json response.  Works for multiple URLs.
  • 19. JSON Query HTTP Service Backend  Redis. key­value data store, can be used as cache.  Fast! compared with memcached? YMMV.  Clustering? Not here yet!  Used it as a concept. Selling point? Virtual Memory  What if we run out of memory?  suitable for large values, keys are requested URLs  Keys in memory, values on disk.  Idea: SSD for memory, slower disk for values.
  • 20. How can I use it? require 'net/http' require 'json' post_data = { :apikey => "dc25ece96592813032f3605e95e8c6e9669cad46", :guid => "123123", :xpath => "//leg[2], //leg[1]", :url => "http://maps.googleapis.com/maps/api/directions/json? origin=Chicago,IL&destination=Los+Angeles,CA&waypoints=Joplin,MO| Oklahoma+City,OK&sensor=false” } document = Net::HTTP.post_form( URI.parse('http://jsonquery.heroku.com/v1/fetch_page') , post_data ) response = JSON.parse( document.body ) xpath_1 = response["ProxyResponse"]["url_1"]["xpath_1"][“response”] xpath_2 = response["ProxyResponse"]["url_1"]["xpath_2"][“response”]
  • 21. Future  XML support.  Redis VM support is dropped in 2.4  Need to investigate memcache, membase, riak and so  on. Many solutions according to domain.  Scale. How?  Usual approach so far is to spawn multiple processes.  Threaded vs Evented.  Unicorn, Mongrel, Thin, Rainbows, Passenger,  Zbattery, Goliath.
  • 22. Bibliography 1) Mocks aren't Stubs. Martin Fowler 2) Service­oriented design with Ruby and Rails. Paul Dix et  al 3) The Rspec book, David Chelimsky et al 4) Rails test prescriptions, Noel Rappin 5) Sinatra and testing from a pro: Peepcode Play­by­Play  (episode 54) with J. Barnette