Podemos escribirjuego verbo-agnóstico en Sinatra
get '/foo' do
...
end
y
post '/foo' do
...
end
que está muy bien. ¿Pero puedo combinar múltiples verbos HTTP en una ruta?
Podemos escribirjuego verbo-agnóstico en Sinatra
get '/foo' do
...
end
y
post '/foo' do
...
end
que está muy bien. ¿Pero puedo combinar múltiples verbos HTTP en una ruta?
Esto es posible a través de la multi-route
extension que forma parte de Sinatra-contrib:
require 'sinatra'
require "sinatra/multi_route"
route :get, :post, '/foo' do
# "GET" or "POST"
p request.env["REQUEST_METHOD"]
end
# Or for module-style applications
class MyApp < Sinatra::Base
register Sinatra::MultiRoute
route :get, :post, '/foo' do
# ...
end
end
Sin embargo, tenga en cuenta que usted puede hacer esto simplemente a sí mismo sin la extensión a través de:
foo = lambda do
# Your route here
end
get '/foo', &foo
post '/foo', &foo
O más elegante como un meta-método:
def self.get_or_post(url,&block)
get(url,&block)
post(url,&block)
end
get_or_post '/foo' do
# ...
end
Usted también podría estar interesado en this discussion on the feature.
utilicé la solución de meta-método, se ve mejor. – molokoV
Phrogz tiene una gran respuesta, pero si cualquiera de lambdas o incluyendo Sinatra-contrib no es para ti, entonces este método meta será lograr el mismo resultado que Sinatra-contrib para sus propósitos:
# Provides a way to handle multiple HTTP verbs with a single block
#
# @example
# route :get, :post, '/something' do
# # Handle your route here
# end
def self.route(*methods, path, &block)
methods.each do |method|
method.to_sym
self.send method, path, &block
end
end
Si no está seguro de poder enviar métodos arbitrarios al self
, puede protegerse configurando una lista blanca de métodos permitidos en una matriz y luego verificando la presencia del símbolo en la matriz.
# Provides a way to handle multiple HTTP verbs with a single block
#
# @example
# route :get, :post, '/something' do
# # Handle your route here
# end
def self.route(*methods, path, &block)
allowed_methods = [:get, :post, :delete, :patch, :put, :head, :options]
methods.each do |method|
method.to_sym
self.send(method, path, &block) if allowed_methods.include? method
end
end
Aquí es un servidor de servicio disponible que he conseguido en una sola línea :)
require 'sinatra';set port: ARGV[0]||80;%w.get post put patch options delete..map{|v|send(v,'*'){503}}
realidad he usado esto para probar el comportamiento de algunos código de cliente en la cara de 503s.
Fwiw, acabo de hacerlo de forma manual, sin métodos de ayuda o extensiones:
%i(get post).each do |method|
send method, '/foo' do
...
end
end
Aunque si lo está haciendo mucho que por supuesto tiene sentido abstracto que fuera.
Esta es la solución perfecta de lejos.Me recuerdas una vez más que todo es Ruby y bloquea :) –
Doy dos soluciones para usted a continuación. Sin embargo, tenga en cuenta esta cita de la [discusión vinculada] (https://github.com/sinatra/sinatra/issues/253#issuecomment-1102620): _ "No estoy al tanto de cuándo es correcto un GET o POST para el mismo camino debe dar como resultado comportamientos/respuestas idénticas. Siempre he encontrado que hay una diferencia menor en el comportamiento, aunque la respuesta puede ser la misma. Para eso son las plantillas/vistas. Cualquier funcionalidad que tengan puede compartir fácilmente puede ser envuelto en otro método. "_ ¿Estás seguro de que realmente quieres la misma ruta exacta para ambos' get' y 'post'? – Phrogz
Gracias. Me gustaría aún poder diferenciar entre los verbos dentro de la ruta. No parece que multi_route sea compatible con esto, pero debe ser trivial para agregar. – punund
He actualizado mi respuesta para mostrar que siempre puede usar 'request.env [" REQUEST_METHOD "]' para determinar qué es el verbo dentro de su ruta. El hecho de que te importe hace que sea aún más evidente que probablemente deberías tener dos rutas separadas con una o más ayudantes y vistas compartidas; sin embargo, la belleza de Sinatra es que no hay una sola manera correcta ... ¡así que disfruta! :) – Phrogz