Upload
bob-nadler-jr
View
1.507
Download
0
Embed Size (px)
Citation preview
Web Development with Sinatra
What is Sinatra?
“Sinatra is a DSL for quickly creating web applications in Ruby with minimal effort.”
- sinatrarb.com/intro
It’s a LIBRARY not a FRAMEWORK.
huh?
http://stackoverflow.com/questions/148747/what-is-the-difference-between-a-framework-and-a-library
http://www.quora.com/Software-Engineering/Whats-the-difference-between-a-library-and-a-framework
“A library is essentially a set of functions that you can call... Each call does some work and returns control to the client.”
“A framework embodies some abstract design, with more behavior built in... you need to insert your behavior into various places in the framework.”
http://martinfowler.com/bliki/InversionOfControl.html
Martin Fowler
Sinatra allows you to structure your application to fit the problem you’re trying to solve instead of the other way around.
Simplest Examplerequire 'sinatra'
get '/hi' do "Hello World!"end
$ gem install sinatra$ ruby hi.rb== Sinatra has taken the stage ..>> Listening on 0.0.0.0:4567
Road Map
• Fundamentals
• “Advanced” Topics
• Use Cases
FundamentalsAnatomy of a Route Handler
HTTP Verbgetpostput
deletepatch
URL
Behavior
get '/hello/:name' do "Hello, #{params[:name]}"end
Parameters
FundamentalsThe First Sufficient Match Wins
get '/*' do "NOM NOM NOM"end
get '/specific' do "I'll never be matched... you'll won't see me!"end
FundamentalsHalting a Request
get '/halt' do "You will not see this output." halt 500end
FundamentalsRedirecting a Request
get '/search' do redirect 'http://www.google.com', 301end
Optional
FundamentalsViews: Inline Templatesrequire 'sinatra'
get '/index' do erb :indexend
__END__
@@index
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>Inline Template</title></head<body> <h1>It Worked!</h1></body></html>
ERB by default, but any templates supported by
Tilt will work
Each inline template must have a unique name
FundamentalsViews: External Templates
Just place your templates in a /views folder and Sinatra will pick them up; you’re route handlers stay the same
FundamentalsViews: Passing Dataget '/home' do @name = 'John Doe' erb :homeend
__END__
@@home
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>Inline Template</title></head<body> <h1><%= @name %></h1></body></html>
FundamentalsFilters
before do content_type :jsonend
after do "After filter called"end
FundamentalsHelpershelpers do def link(name) case :name when :about then '/about' when :index then '/index' else "/page/#{name}" endend
# in your view template<a href="<%= link :about %>">About</a>
# -- OR --# define helpers as methods in a module
module MyHelpers # helper methodsend
helpers MyHelpers
FundamentalsConfiguration
configure :development do set :db, Sequel.sqlite('db/development.sqlite')end
configure :production do set :db, Sequel.connect(ENV['DATABASE_URL'])end
FundamentalsCaching
get '/cache' do expires 3600, :public, :must_revalidate "This page rendered at #{Time.now}."end
See http://www.mnot.net/cache_docs/ for an explanation of HTTP caching options
FundamentalsSessionsconfigure do enable :sessionsend
get '/set' do session[:foo] = Time.now "Session time was set."end
get '/fetch' do "Session value: #{session[:foo]}"end
get '/unset' do session.clear redirect '/fetch'end
FundamentalsAttachments
before do content_type :txtend
get '/attachment' do attachment 'path/to/my-attachment.txt'end
FundamentalsTesting with rack-testrequire 'my_sinatra_app'require 'test/unit'require 'rack/test'
class MyAppTest < Test::Unit::TestCase include Rack::Test::Methods
def app Sinatra::Application end
def test_my_default get '/' assert_equal 'Hello World!', last_response.body end
def test_with_params get '/meet', :name => 'Frank' assert_equal 'Hello Frank!', last_response.body end
def test_with_rack_env get '/', {}, 'HTTP_USER_AGENT' => 'Songbird' assert_equal "You're using Songbird!", last_response.body endend
Advanced TopicsModular vs. “Classic”
“For some reason, it is a common misconception that modular applications are superior to classic applications, and that really advanced users only
use modular style... This is utter nonsense and no one on the Sinatra core team shares this view.
Sinatra is all about simplicity and if you can use a classic application, you should.”
-- Sinatra Up and Running
Advanced TopicsReasons to Use Modular
you don’t want to pollute the Object namespace (writing a Gem)
combining multiple Sinatra apps in a single process
use Sinatra app as middleware
Advanced TopicsSimplest Modular Examplerequire 'sinatra/base'
class MyApp < Sinatra::Base get '/hi' do "Hello World!" end # Only start the server if the file # has been executed directly # # $0 is the executed file # __FILE__ is the current file run! if __FILE__ == $0end
Advanced TopicsRunning with Rack: Rackup File# In a file named my_app.rbrequire 'sinatra/base'
class MyApp < Sinatra::Base get '/hi' do "Hello World!" endend
# in a separate file named config.rurequire './my_app'run MyApp
# launch the server using# rackup command or shotgun
Advanced TopicsRunning with Rack: Middleware Chain# In a file named my_app.rbrequire 'sinatra/base'
class Foo < Sinatra::Base get('/foo') { 'foo' }end
class Bar < Sinatra::Base get('/bar') { 'bar' } use Fooend
# config.rurequire 'my_app'run Bar
# Or Foo and Bar can be in separate files# remember... it's just Ruby!
Advanced TopicsRunning with Rack: Cascaderequire 'sinatra/base'
class Foo < Sinatra::Base get('/foo') { 'foo' }end
class Bar < Sinatra::Base get('/bar') { 'bar' }end
# config.rurequire 'my_app'run Rack::Cascade, [Foo, Bar]
# Differences:# * _slightly_ better performance, but only if you have a lot of endpoints# * you can use any Rack app (like Rails)
Advanced TopicsExtensions: LinkedIn Example
Use Cases
Prototyping Web Apps
API Server for iOS / Android / JavaScript Apps
HTML5 Mobile Apps
Resources• http://rubydoc.info/gems/sinatra/file/README.rdoc
• http://www.sinatrarb.com/documentation
• Sinatra: Up and Running (http://shop.oreilly.com/product/0636920019664.do)
• http://stackoverflow.com/questions/148747/what-is-the-difference-between-a-framework-and-a-library
• http://www.quora.com/Software-Engineering/Whats-the-difference-between-a-library-and-a-framework
• http://martinfowler.com/bliki/InversionOfControl.html
• http://www.mnot.net/cache_docs/
• https://github.com/bnadlerjr/sidestep
• https://github.com/bnadlerjr/leaflet
• https://github.com/bnadlerjr/sinatra-linkedin
• https://github.com/bnadlerjr/fuelyo
• http://rubygems.org/gems/middleman