Revista Informática

Sinatra desde Cero: Enrutamiento (continuación)

Publicado el 24 octubre 2013 por Codehero @codeheroblog

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]}" end

12345 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.

$ curl --request GET localhost:4567/alberto Hola, alberto%

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 end

123456 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 end

12345678 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.

require 'sinatra' get '/:nombre' do "Hola, #{params[:nombre]} y #{params[:segundo]}" end

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].

require 'sinatra' get '/*' do "Se recibió usando un wild card este parámetro: #{params[:splat]}" end

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!" end

12345 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.

require 'sinatra' get '/error' do 'Este mensaje no se va a ver' halt 500 end

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”

$ curl --request GET --verbose localhost:4567/error * About to connect() to localhost port 4567 (#0) * Trying 127.0.0.1... * connected * Connected to localhost (127.0.0.1) port 4567 (#0) > GET /halt HTTP/1.1 > User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5 > Host: localhost:4567 > Accept: */* > < HTTP/1.1 500 Internal 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

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:*/*>&lt;HTTP/1.1500Internal Server Error&lt;Content-Type:text/html;charset=utf-8&lt;X-XSS-Protection:1;mode=block&lt;X-Content-Type-Options:nosniff&lt;X-Frame-Options:SAMEORIGIN&lt;Content-Length:0&lt;*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!" end

1234567891011121314 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 end

123456789 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!


Volver a la Portada de Logo Paperblog