¿Para quién es este artículo?

Este artículo está dirigido a persona que ya tienen conocimiento de ruby y rails pero que desean profundizar y entender como funciona por detrás Rails y otros frameworks MVC

 ¿Por qué deberías leer esto?

Porque aprenderás como funciona Rack el cuál es la base de la gran mayoría de frameworks escritos en Ruby, incluido Ruby On Rails, además entenderás como hace Rails para manejar el enrutamiento, y como funcionan realmente los controllers.

Debería construir mi propio framework?

Si, pero solo por motivos de aprendizaje, nunca deberías ocupar un framework propio para producción, es mucho más seguro y mantenible ocupar frameworks creados por la comunidad.

Capítulo 1, introducción a Rack

Empezamos con nuestra primera aplicación

Para crear la aplicación utilizaremos como base Rack, rack es una interfaz para crear web servers y es utilizada por la mayoría de los frameworks de ruby.

Como base crearemos una carpeta llamada miframework, para nuestra primera aplicación primero crearemos el archivo Gemfile, donde agregaremos la gema Rack

# Gemfile
source "https://rubygems.org"
ruby '2.3.1'
gem 'rack'

Luego instalaremo la gema Rack con bundle

Nuestro siguiente paso es crear la aplicación básica, para eso crearemos el archivo app.rb

#app.rb
class App
  def call()
    [200, {}, ["hola mundo"]]
  end
end
  • El HTTP status code
  • Los headers
  • La respuesta (el body)

El siguiente paso es crear un archivo llamado config.ru que tiene la instrucciones para inicializar rack

#config.ru
require "./app"
run App.new

Para ejecutar nuestra primera aplicación correremos rackup en el terminal y obtendremos un mensaje como el siguiente:

Puma starting in single mode...
* Version 3.6.0 (ruby 2.3.1-p112), codename: Sleepy Sunday Serenity
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:9292
Use Ctrl-C to stop

Al ingresar con el navegador a la dirección localhost:9292 y veremos nuestro mensaje de hola mundo

En el ejemplo ya vimos el body y el status code, pero todavía nos queda algo pendiente, los headers, esto nos permiten diversas acciones como especificar el tipo de contenido del documento y obtener una página web en lugar de un texto plano.

#app.rb
class App
  def call()
    [200, {"Content-Type" => "text/html"}, ["<h1> hola mundo </h1>"]]
  end
end

El hash env

Un función muy importante de Rack es la de capturar toda la información del entorno (environment) y la convierte en un hash que podemos utilizar, esta información nos permitirá realizar diversas acciones como redirigir al usuario dependiendo de la URL.

#app.rb
class App
  def call(env)
    puts env
    [200, {}, ["hola mundo"]]
  end
end

Al reiniciar el servidor y recargar la página podremos ver toda la información del entorno, dentro de este hash veremos diversos pares de clave valor, incluyendo los siguientes.

{
    "QUERY_STRING" => "", 
    "REQUEST_METHOD" => "GET", 
    "REQUEST_PATH" => "/etc", 
}   

El request path

Sin llevar más lejos el ejemplo anterior podríamos mostrar un string con la ruta donde se encuentra el usuario actualmente utilizando el hash env con el key REQUEST_PATH

# app.rb
class App
  def call(env)
    [200, {}, [env['REQUEST_PATH']] ]
  end
end

Manejando distintas rutas

Utilizando el mismo request_path y un if (o case) podemos dirigir al usuario a páginas específicas.

# app.rb
class App
  def call(env)
    case env['REQUEST_PATH']
    when /hola/
      [200, {"Content-Type" => "text/html"}, ["Hola mundo"]]
    else
      [404, {"Content-Type" => "text/html"}, ["Esta p&aacute;gina no existe :("]]
    end
  end
end

Si miramos ambos ejemplos veremos:

content-plain

En el primer caso vemos el resultado como texto plano, en el segundo como HTML.

content-html

En el siguiente capítulo estudiaremos como crear un router junto a un archivo de rutas.