This document provides an overview and introduction to using the Sinatra web framework for building RESTful web applications in Ruby. It discusses Sinatra's philosophy of being simple and easy to use, introduces REST principles and how Sinatra supports them through HTTP verbs, routing, caching, authentication and more. Code examples are provided to demonstrate how a basic "Hello World" application is structured in Sinatra and how requests are routed and executed under the hood.
3. About me
I’m a software developer in
CodicePlastico.
I write Web applications in C# with
ASP.NET MVC. I’m a member of
<WEBdeBS/> a local web
community.
...and I’m a wannabe Ruby
developer ;-)
4. Agenda
‣ Philosophy.
Sweet and easy.
‣ REST.
Yet another boring introduction.
‣ Hello world.
Show some magic.
‣ Features.
Amazing!
‣ Inside.
How it works?
‣ Q&A.
...and thanks.
10. Hello world
~$ gem install sinatra
~$ vi app.rb
require 'sinatra'
get '/' do
'hello world!'
end
11. Hello world
~$ gem install sinatra
~$ vi app.rb
require 'sinatra'
get '/' do
'hello world!'
end
~$ ruby app.rb
13. Is it really so easy?
‣ Yep! (special thanks to Ruby
sweeties)
- get is a just a method (more later)
- the route is the parameter
- the block is what should be
executed
- the block returns the result
- the server is built in (based on Rack)
22. Routing Conditions
get '/foo', :agent => /Mozilla/(d.d)s
w?/ do
"You're using Mozilla version
#{params[:agent][0]}"
end
get '/foo' do
# Matches non-Mozilla browsers
end
23. Routing Custom
set(:prob) { |v| condition { rand <= v } }
get '/win_a_car', :prob => 0.1 do
"You won!"
end
get '/win_a_car' {"Sorry, you lost."}
24. Xml or Json
‣ You can set the content_type to
whatever you need
content_type :json
content_type :xml
28. Cache
‣ You can set your cache information
using the headers method
headers "Cache-Control" => "public,
must-revalidate, max-age=3600",
"Expires" => Time.at(Time.now.to_i + (60
40. Modular Apps
Multi file
Subclassing Sinatra::Base
Distributed as library
41. The code
What happen when a request arrives?
get (‘/hello’) do { ‘hello world’ }
42. Where do get come from?
require "sinatra"
outer_self = self
get '/' do
"outer self: #{outer_self}, inner self: #{self}"
end
outer self: main, inner self: #<Sinatra::Application:
closures in ruby are “scope gate”
55. Where do get come from?
‣ get is defined twice:
– Once in Sinatra::Delegator a mixin
extending Object
– Once in Sinatra::Application
‣ The Delegator implementation simply
delegate to Application
‣ That’s why we have get/post/...
methods on main
56. How the block is invoked?
‣ The route! method finds the correct
route
def route_eval
throw :halt, yield
end
‣ throw is used to go back to the invoker
57. In base.rb
‣ The invoker
def invoke
res = catch(:halt) { yield }
# .... other code...
end