Sinatra¶
- Sinatra
- Sinatra instalación
- Sinatra hola mundo minimalista
- Sinatra rutas
- Sinatra rutas condicionales
- Sinatra rutas verificación personalizada
- Sinatra rutas valores devueltos
- Sinatra contenido estático
- Sinatra vistas plantillas
- Sinatra configuración
- REST
- Páginas hijas embutidas
- Otras páginas relacionadas
- Referencias
Sinatra instalación¶
Fedora:
$ su -c "yum install rubygem-sinatra"
gem:
$ su -c "gem install sinatra"
Mi versión de trabajo para el momento de redacción.
$ gem list sinatra *** LOCAL GEMS *** sinatra (1.2.6)
Sinatra hola mundo minimalista¶
hola-mundo-minimalista.rb
1require 'rubygems' if RUBY_VERSION < '1.9'
2require 'sinatra';
3get '/' do
4'¡Hola mundo minimalista en Sinatra!'
5end
Ejecute y apunte su navegador al puerto local 4567.
$ ruby hola-mundo-minimalista.rb == Sinatra/1.2.6 has taken the stage on 4567 for development with backup from Mongrel 127.0.0.1 - - [06/Dec/2011 13:29:49] "GET / HTTP/1.1" 200 36 0.0681 127.0.0.1 - - [06/Dec/2011 13:29:49] "GET /favicon.ico HTTP/1.1" 404 447 0.0011 127.0.0.1 - - [06/Dec/2011 13:29:49] "GET /favicon.ico HTTP/1.1" 404 447 0.0009 ...
Pongamos algo dinámico.
1require 'rubygems' if RUBY_VERSION < '1.9'
2require 'sinatra';
3get '/' do
4 "¡Hola mundo minimalista en Sinatra!<br> #{Time.now}"
5end
Sinatra rutas¶
En Sinatra una ruta es un método apareado con un patrón URL. Cada ruta es asociada con un bloque:
1 get '/' do
2 .. muestra algo ..
3 end
4
5 post '/' do
6 .. crea algo ..
7 end
8
9 put '/' do
10 .. reemplaza algo ..
11 end
12
13 patch '/' do
14 .. modifica algo ..
15 end
16
17 delete '/' do
18 .. aniquila algo ..
19 end
20
21 options '/' do
22 .. dar alternativas de algo ..
23 end
Las rutas son verificadas en el orden que son definidas. La primera ruta que haga coincidencia es invocada.
Los patrones para las rutas pueden incluir parámetros con nombres accesibles via el hash params:
1 get '/hola/:nombre' do
2 # coincide con "GET /hola/foo" y "GET /hola/bar"
3 # params[:nombre] es 'foo' o 'bar'
4 "Hola #{params[:nombre]}!"
5 end
También puede acceder a los parámetros con nombre via parámetros de bloque:
1 get '/hola/:nombre' do |n|
2 "Hola #{n}!"
3 end
Los patrones de ruta también pueden incluir parámetros splat (o wildcard) accesible via el array params[:splat]:
1 get '/di/*/a/*' do
2 # coincide con /di/hola/a/mundo
3 params[:splat] # => ["hola", "mundo"]
4 end
5
6 get '/descarga/*.*' do
7 # coincide con /descarga/ruta/al/archivo.xml
8 params[:splat] # => ["ruta/al/archivo", "xml"]
9 end
O con parámetros de bloque:
1 get '/descarga/*.*' do |ruta, ext|
2 [ruta, ext] # => ["ruta/a/archivo", "xml"]
3 end
La verificación de rutas con expresiones regulares:
1 get %r{/hola/([\w]+)} do
2 "Hola, #{params[:captures].first}!"
3 end
O con un parámetro de bloque:
1 get %r{/hola/([\w]+)} do |c|
2 "Hola, #{c}!"
3 end
Los patrones de ruta pueden tener opcionalmente parámetros:
1 get '/posts.?:format?' do
2 # coincide con "GET /posts" y cualquier extension "GET /posts.json", "GET /posts.xml" etc.
3 end
Por cierto que, a menos que deshabilite "path traversal attack protection", el request path puede ser modificado antes de hacer la verificación con sus rutas.
Sinatra rutas condicionales¶
Las rutas pueden incluir una variedad de condicionales a verificar, tal como el agente de usuario (cliente):
1 get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
2 "Usted está usando Songbird version #{params[:agent][0]}"
3 end
4
5 get '/foo' do
6 # Coincide con navegadores diferentes a songbird
7 end
Otros condicionales disponibles son host_name y provides:
1 get '/', :host_name => /^admin\./ do
2 "Area Admin, Acceso rechazado!"
3 end
4
5 get '/', :provides => 'html' do
6 haml :index
7 end
8
9 get '/', :provides => ['rss', 'atom', 'xml'] do
10 builder :feed
11 end
Usted puede fácilmente definir sus condicionales:
1 set(:probabilidad) { |valor| condition { rand <= valor } }
2
3 get '/ganarme_un_carro', :probabilidad => 0.1 do
4 "¡Ganó!"
5 end
6
7 get '/ganarme_un_carro' do
8 "Lo lamentamos, pierdes."
9 end
Para una condición tome múltiples valores use un splat:
1 set(:auth) do |*roles| # <- note el splat aquí
2 condition do
3 unless logged_in? && roles.any? {|role| current_user.in_role? role }
4 redirect "/login/", 303
5 end
6 end
7 end
8
9 get "/mi/cuenta/", :auth => [:user, :admin] do
10 "Detalles de su cuenta"
11 end
12
13 get "/solo/admin/", :auth => :admin do
14 "¡Sólo se permiten admins aquí!"
15 end
Sinatra rutas verificación personalizada¶
Como ya probablemente sabe, Sinatra incluye el soporte para utilziar patrones String y expresiones regulares como método de verificación de rutas. Sin embargo la historia no termina allí, usted puede fácilmente definir sus propios métodos para verificación de la ruta a tomar.
1 class AllButPattern
2 Match = Struct.new(:captures)
3
4 def initialize(except)
5 @except = except
6 @captures = Match.new([])
7 end
8
9 def match(str)
10 @captures unless @except === str
11 end
12 end
13
14 def all_but(pattern)
15 AllButPattern.new(pattern)
16 end
17
18 get all_but("/index") do
19 # ...
20 end
Note que en el ejemplo arriba también puede ser expresado como:
1 get // do
2 pass if request.path_info == "/index"
3 # ...
4 end
O usando búsqueda de valor negativo:
1 get %r{^(?!/index$)} do
2 # ...
3 end
Sinatra rutas valores devueltos¶
El valor devuelto de un bloque de ruta determina al menos el cuerpo de la respuesta (body) hacia el cliente HTTP, o como mínimo, pasado al siguiente middleware en la pila Rack. Lo más común es que sea una cadena de caracteres (string) como en ejemplos anteriores, pero se aceptan otros valores.
Usted puede devolver cualquier objeto que sea una respuesta válida Rack, un objeto Rack body o un código de estado HTTP:
- Un Array con tres elementos: [status (Fixnum), headers (Hash), response body (responds to #each)] .
- Un Array con dos elementos: [status (Fixnum), response body (responds to #each)] .
- Un objeto que responda a #each y pase nada sino strings al bloque dado.
- Un Fixnum que represente un código de estado.
La forma en que fácilmente se puede implementar un ejemplo de streaming sería:
1 class Stream
2 def each
3 100.times { |i| yield "#{i}\n" }
4 end
5 end
6
7 get('/') { Stream.new }
Usted también puede usar el método ayudante stream (descrito más adelante) para reducir y embutir la lógica en la ruta.
Sinatra contenido estático¶
Los archivos estáticos son servidos desde el directorio ./public. Puede especificar una ubicación diferente ajustando la opción :public_folder:
1 set :public_folder, File.dirname(__FILE__) + '/static'
Note que el nombre del directorio público no está incluido en el URL. Un archivo ./public/css/style.css estaría disponible por ejemplo como ejemplo.com/css/style.css.
Use el ajuste :static_cache_control para agregar información en la cabecera referente a Cache-Control.
Sinatra vistas plantillas¶
Cada lenguaje de plantilla es expuesto con sus propios métodos de despliege (rendering). Dichos métodos simplemente devuelven un string:
1 get '/' do
2 erb :index
3 end
Este código despliega views/index.erb.
En vez de un nombre de plantilla se puede simplemente pasarle el contenido de una plantilla directamente:
1 get '/' do
2 code = "<%= Time.now >"
3 erb code
4 end
Las plantillas usan un segundo argumento, el hash options:
1 get '/' do
2 erb :index, :layout => :post
3 end
Esto desplegará views/index.erb embutido en views/post.erb (por omisión es views/layout.erb, si existe).
Cualquier opción que no entienda Sinatra será pasada al motor de la plantilla:
1 get '/' do
2 haml :index, :format => :html5
3 end
También puede establecer las opciones por plantilla de forma general:
1 set :haml, :format => :html5
2
3 get '/' do
4 haml :index
5 end
Las opciones pasadas al método render se imponen a las opciones establecidas por set.
Opciones disponibles:
- locals : lista de locals pasados al documento. Útil con partials. Ejemplo: erb "<%= foo %>", :locals => {:foo => "bar"}
- default_encoding : codificación de los string a usar si no es conocido. Por omisión se pone a lo que diga settings.default_encoding.
- views : directorios de vistas desde el cual cargar las plantillas. Por omisión se pone a lo que diga settings.views.
- layout : si usar o no un layout (true o false), si es un Symbol, especifica qué plantilla usar. Ejemplo: erb :index, :layout => !request.xhr?
- content_type : Content-Type que la plantilla produce, el valor por omisión depende del lenguaje de plantilla.
- scope : Scope to render template under. Por omisión es la instancia de aplicación. Si lo cambia, las variables de instancia y los métodos ayudantes no estarán disponibles.
- layout_engine : Motor de plantillas a usar para desplegar el layout. Útil en el caso de lenguages que no soportan layouts de otra forma. El valor por omisión es el mismo al del motor utilizado por la plantilla. Ejemplo: set :rdoc, :layout_engine => :erb
Las plantillas se asumen estar localizadas directamente bajo el directorio ./views. Para usar un directorio diferente para las vistas:
1 set :views, settings.root + '/templates'
Algo importante de recordar es que usted debe siempre referenciar las plantillas con symbols, incluso si se encuentran en un subdirectorio (en dicho caso, use :'subdir/template'). Usted debe usar un symbol porque de otra forma los métodos de despliegue procesarían los strings pasados a ellos directamente.
Sinatra configuración¶
Ejecute de una vez, al inicio, en cualquier entorno:
1 configure do
2 # ajuste de una opción
3 set :option, 'value'
4
5 # ajuste de múltiples opciones
6 set :a => 1, :b => 2
7
8 # equivale a `set :option, true`
9 enable :option
10
11 # equivale a `set :option, false`
12 disable :option
13
14 # también puede tener ajustes dinámicos con bloques
15 set(:css_dir) { File.join(views, 'css') }
16 end
Ejecute sólo cuando el entorno (variable de entorno RACK_ENV) esté definido a :production:
1 configure :production do
2 ...
3 end
Ejecute cuando el entorno esté puesto a :production o :test:
1 configure :production, :test do
2 ...
3 end
Usted puede acceder a dichas opciones por medio de settings:
1 configure do
2 set :foo, 'bar'
3 end
4
5 get '/' do
6 settings.foo? # => true
7 settings.foo # => 'bar'
8 ...
9 end
Configurando protección de ataque¶
Sinatra usa Rack::Protection para defender su aplicación de los más ataques oportunísticos. Usted puede deshabilitar este comportamiento (que debería resultar en mejoras del desempeño):
1 disable :protection
Para saltarse una capa de defensa, defina protection con un un hash de opciones:
1 set :protection, :except => :path_traversal
Usted también le puede pasar un array con la finalidad de deshabilitar una serie de protecciones:
1 set :protections, :except => [:path_traversal, :session_hijacking]
Ajustes disponibles¶
- absolute_redirects
- Si se deshabilita, Sinatra permitirá redirecciones relativas, sin embargo, Sinatra ya no estará en conformidad con RFC 2616 (HTTP 1.1) que sólo permite redirección absolutas.
- Habilite si su app está corriendo detrás de un proxy reverso que no ha sido configurado apropiadamente. Note que el ayudante url aún así producirá URLs absolutos, a menos que le pase false como segundo parámetro.
- Está deshabilitado por omisión.
- add_charsets
- Tipos mime que el ayudante content_type agregará automáticamente acerca de charset info.
- Usted debería agregar en vez de sobrescribir en esta opción:
1settings.add_charsets << "application/foobar"
- app_file
- Archivo principal de la aplicación, utilizado para detectar la raíz del proyecto, vistas, el directorio público y plantillas inline.
- bind
- Dirección IP a uar (por omisión: 0.0.0.0). Sólo se usa con el serivodr buil-in.
- default_encoding
- Codificación utilizada si no se especifica (por omisión "utf-8").
- dump_errors
- Muestra los errores en el log.
- environment
- Entorno actual, por omisión ENV['RACK_ENV'], o "development" si no está disponible.
- logging
- Usar el logger.
- lock
- Coloca un enganche en cada solicitud, sólo ejecutando el procesamiento por solicitud por proceso Ruby concurrentemente.
- Habilite si su app no es thread-safe. Deshabilitado por omisión.
- method_override
- Usa _method magic para permitir formularios put/delete en los browsers que no lo soportan.
- port
- Puesto en el que escuchar. Sólo se usa con el servidor built-in.
- prefixed_redirects
- Si insertar o no request.script_name en las redirecciones si no se da una ruta absoluta. De esa forma redirigir '/foo' se comportará como redirigir a('/foo'). Deshabilitado por omisión.
- protection
- Si habilitar o no las protecciones de ataque web.
- public_folder
- Directorio desde donde se sirven los archivos públicos.
- reload_templates
- Si recargar las plantillas entre solicitudes o no. Habilitado en modo development.
- root
- Directorio raíz del proyecto.
- raise_errors
- Levantar excepciones (detendrá la aplicación).
- run
- Si se habilita, Sinatra manejará el arranque del servidor web, no use si está usando rackup o otros medios.
- running
- ¿Está corriendo el servidor built-in ahora? ¡No cambie!
- server
- Servidor o lista de servidores a usar para servidor built-in, por omisión es [‘thin’, ‘mongrel’, ‘webrick’], el orden indica la prioridad.
- sessions
- Habilitar sesiones basadas en cookie.
- show_exception
- Muestra una traza de la pila en el browser.
- static
- De si Sinatra debe servir archivos estáticos.
- Deshabilite cuando tenga un servidor capaz de hacerlo.
- Deshabilitar provoca un incremento en el desempeño.
- Habilitado por omisión en estilo clásico, deshabilitado para apps modulares.
- static_cache_control
- Cuando Sinatra sirve archivos estáticos, configure para agregar encabezados Cache-Control en las respuestas.
- Utiliza el ayudanete cache_control.
- Deshabilitado por omisión.
- Use un array explícito cuando quiera ajustar múltiples valores:
1set :static_cache_control, [:public, :max_age => 300]
- threaded
- Si se pone a true, le indicará a Thin que use EventMachine.defer para procesar la solicitud.
- views
- Directorio de las vistas.
REST¶
- http://github.com/blindgaenger/sinatra-rest
- http://mifo.sk/creating-rest-based-api-with-sinatra-rabbit y https://github.com/mifo/sinatra-rabbit
- sinatra servidor rest tuto
Páginas hijas embutidas¶
Ya las páginas enlazadas abajo están embutidas en esta página, están listadas aquí sólo para que el editor pueda localizarlas más rápido.
- sinatra instalación
- sinatra hola mundo minimalista
- sinatra rutas
- sinatra rutas valores devueltos
- sinatra_rutas condicionales
- sinatra rutas verificación personalizada
- sinatra contenido estático
- sinatra vistas plantillas
- sinatra con AR
- sinatra testing
- sinatra configuración
