Para comprender correctamente todo lo que hablaremos en esta serie, es conveniente tener un conocimiento básico sobre el lenguaje de Ruby. Podrás conseguir toda la información desees aquí
Enrutamiento
La semana pasada estuvimos hablando y realizando unas pequeñas pruebas de enrutamiento para aprender como funcionan los distintos verbos HTTP con los que trabaja Sinatra. Esta semana extenderemos el uso de los distintos verbos y agregaremos complejidad al mostrar casos reales en el manejo de rutas.
Parámetros
Cuando desarrollamos una aplicación web que necesita variar su comportamiento dependiendo de qué y quién la esté usando, empleamos el paso de parámetros, lo que nos permite poder interactuar directamente con la aplicación sin variar su código fuente.
¿Cómo se utiliza el paso de parámetros en Sinatra? Pues es relativamente sencillo, vamos a verlo para los 3 casos ‘GET’, ‘POST’, ‘PUT’.
require 'sinatra' get '/:nombre' do "Hola, #{params[:nombre]}" end12345 require'sinatra' get'/:nombre'do "Hola, #{params[:nombre]}"end
Hemos utilizado un parámetro llamado nombre
que “almacena” cualquier palabra pero se está utilizando para recibir el nombre de una persona y luego imprime el mismo por pantalla.
12 $curl--request GET localhost:4567/albertoHola,alberto%
De esta manera cualquier nombre que le pasemos a través de ese URL se verá reflejado al imprimir el “markup”.
Si ahora nos encontráramos en una aplicación con un formulario de inicio de sesión y enviamos el nombre de usuario y contraseña por ‘POST’ se recibiría así:
require 'sinatra' post '/login' do username = params[:username] # Nombre de usuario password = params[:password] # Contraseña end123456 require'sinatra' post'/login'do username=params[:username]# Nombre de usuario password=params[:password]# Contraseñaend
Si quisiéramos modificar los datos de un usuario previamente creado en una base de datos haríamos lo siguiente con una petición de tipo ‘PUT’:
require 'sinatra' put '/usuario/:id' do Usuario u = Usuario.find(params[:id])  u.primer_nombre = params[:primer_nombre] u.segundo_nombre = params[:segundo_nombre] u.save end12345678 require'sinatra' put'/usuario/:id'do Usuariou=Usuariofind(params[:id]) uprimer_nombre=params[:primer_nombre] usegundo_nombre=params[:segundo_nombre] usaveend
Esto lo que realiza es buscar el usuario con el “id” en base de datos utilizando un ORM para esto y una vez que lo ha encontrado modifica sus datos con los que se encuentran en el formulario de “editar usuario” en la página.
Query Strings
¿Qué son “query strings”? posiblemente habrán visto en algún momento en un URL un parámetro con esta representación ?variable=hola
, los mismos pueden ser utilizados para pasar información muy particular como lo puede ser muchas veces el idioma de la página. Si te gustan mucho los URL limpios estoy muy seguro de que vas a obviar los “query strings” lo mayor posible.
12345 require'sinatra' get'/:nombre'do "Hola, #{params[:nombre]} y #{params[:segundo]}"end
$ curl --request GET localhost:4567/alberto?segundo=jonathan Hola, alberto y jonathan%12 $curl--request GET localhost:4567/alberto?segundo=jonathanHola,albertoyjonathan%
Cualquier nombre o palabra que escribamos en el “query string” ?segundo=
se mostrará en pantalla.
Wild Cards (Comodines)
Las rutas con “wild cards” se representan con el carácter ** (*) ** y quiere decir que son capaces de recibir cualquier tipo de parámetro que se desee. Para poder recibir un parámetro con “wild card” se debe utilizar params[:splat]
.
12345 require'sinatra' get'/*'do "Se recibió usando un wild card este parámetro: #{params[:splat]}"end
El resultado es el siguiente:
$ curl --request GET localhost:4567/hola Se recibió usando un wild card este parámetro: ["hola"]%12 $curl--request GET localhost:4567/holaSe recibióusando un wild card este parámetro:["hola"]%
Expresiones regulares
Podemos utilizar expresiones regulares para crear y adaptar rutas que den la misma respuesta a distintos casos. Por ejemplo: para agregar un usuario o un administrador se podría realizar captando la petición por una misma ruta para luego definir que tipo de usuario se desea agregar utilizando función interna dentro de la ruta que capturó la petición.
require 'sinatra' get %r{/(c|h)ola} do "La ruta funciona para las dos palabras!" end12345 require'sinatra' get%r{/(c|h)ola}do "La ruta funciona para las dos palabras!"end
Si comprobamos la respuesta que obtenemos podemos observar que es exactamente la misma.
$ curl --request GET localhost:4567/hola La ruta funciona para las dos palabras!% $ curl --request GET localhost:4567/cola La ruta funciona para las dos palabras!%12345 $curl--request GET localhost:4567/holaLa ruta funciona para las dos palabras!% $curl--request GET localhost:4567/colaLa ruta funciona para las dos palabras!%
Halting (Interrupción)
Este tipo de ruta la utilizamos cuando queremos finalizar una operación ya sea porque se está tardando demasiado tiempo o simplemente ha ocurrido un problema grave del lado del servidor. Cabe destacar que lo que realiza este comportamiento es la función halt
que nos proporciona Sinatra en el DSL. El mensaje 500
es simplemente uno de los códigos de error existenten que representan problemas del lado del servidor.
123456 require'sinatra' get'/error'do 'Este mensaje no se va a ver' halt500end
Si observamos la salida con un --verbose
para ver en detalle que ocurre, podremos apreciar que nos devuelve un “server error”
12345678910111213141516171819 $curl--request GET--verbose localhost:4567/error*About toconnect()tolocalhost port4567(#0)* Trying127.0.0.1...*connected*Connected tolocalhost(127.0.0.1)port4567(#0)>GET/halt HTTP/1.1>User-Agent:curl/7.24.0(x86_64-apple-darwin120)libcurl/7.24.0OpenSSL/0.9.8yzlib/1.2.5>Host:localhost:4567>Accept:*/*><HTTP/1.1500Internal Server Error<Content-Type:text/html;charset=utf-8<X-XSS-Protection:1;mode=block<X-Content-Type-Options:nosniff<X-Frame-Options:SAMEORIGIN<Content-Length:0<*Connection#0 to host localhost left intact*Closing connection#0
Pasando una petición
Cuando hablamos sobre las rutas con expresiones regulares dijimos que al utilizarlas se podía responder a distintos comportamientos de le la misma en “funciones internas”. El paso de peticiones es una manera de realizar esto de manera sencilla, observemos el ejemplo:
require 'sinatra' before do content_type :txt end get %r{/(c|h)ola} do pass if request.path =~ /\/hola/ "Estoy sirviendo la petición para /cola!" end get '/hola' do "servido desde /hola!" end1234567891011121314 require'sinatra' before do content_type:txtend get%r{/(c|h)ola}do pass ifrequestpath=~/\/hola/ "Estoy sirviendo la petición para /cola!"end get'/hola'do "servido desde /hola!"end
Veamos la los resultados:
$ curl --request GET localhost:4567/cola Estoy sirviendo la petición para /cola!% $ curl --request GET localhost:4567/hola servido desde /hola!%1234 $curl--request GET localhost:4567/colaEstoy sirviendo la peticiónpara/cola!% $curl--request GET localhost:4567/holaservido desde/hola!%
Redireccionando
Este tipo de ruta la utilizamos cuando queremos re-dirigir al usuario a un otra dirección ya sea dentro o fuera de nuestro dominio. A esta función le podemos pasar un código a la petición para notificar si el mismo es una re-dirección temporal o permanente.
require 'sinatra' get '/redirect' do redirect 'http://www.google.com' end get '/redirect2' do redirect 'http://www.google.com', 301 end123456789 require'sinatra' get'/redirect'do redirect'http://www.google.com'end get'/redirect2'do redirect'http://www.google.com',301end
Todos los ejemplos utilizados en este curso fueron extraídos del libro Sinatra: Up and Running
Conclusión
En este tercer capítulo, terminamos de explicar los conceptos básicos a cerca de enrutamiento en Sinatra y como se utilizan. A partir de este momento pueden sacar provecho de estos tres capítulos para empezar a desarrollar una pequeña aplicación de pruebas. Si te surge algún tipo de duda no te detengas y déjanos un comentario, que gustosamente lo responderemos.
¡Hasta el próximo capítulo!