martes, 13 de marzo de 2012

Pregúntale al pato.

Estoy seguro de que en más de una ocasión se han quedado detenidos pensando en algún problema que surgió y que no saben cómo resolver. Suele ocurrirme mucho en el trabajo, cuando de repente tengo un error en alguna parte del código y al preguntarle a Mr. Google no encuentro nada.


Para quienes, como yo, se dedican a programar (o algo que tenga que ver con IT), seguro se habrán topado con stackoverflow. En StackOverflow, una vez registrado, puedes realizar preguntas acerca del problema de IT que te aqueja, y (en mi experiencia), en sólo unas horas alguien responde, y si bien es posible que no te resuelva por completo el problema, seguro te ayudará a descubrir el camino para resolverlo tú mismo.


La filosofía detrás del sistema de preguntas y respuestas con la que funciona dicha página es muy interesante, y plantea una muy ingeniosa metodología para que realmente pienses en tu problema. Es más,  es muy probable que al pensar cómo plantear tu pregunta logres encontrar la respuesta tú solito.


En palabras de uno de los fundadores del sitio, Jeff Atwood (cuyo blog ha sido una excelente inspiración para mí y se los recomiendo fervientemente), la filosofía detrás de StackOverflow se puede resumir en 3 palabras: "Pregúntale al pato". 


No, no es broma, es una metodología perfectamente válida. Todo surgió gracias a una historia publicada aquí. Les ofrezco una traducción un tanto burda:


Bob señaló a una esquina de la oficina. "Ahí está un pato", dijo. "Quiero que le hagas tu pregunta al pato". 
Miré al pato. Era un pato evidentemente muerto, de peluche. Incluso si no hubiera estado muerto, seguramente no sería una buena fuente de información sobre diseño. Miré a Bob, pero su mirada era totalmente seria. Además, era mi jefe, así que no tenía mucha alternativa.
Un tanto apenado, me acerqué al pato con la cabeza baja, como si fuera a rezarle. En eso, Bob me encrespó: "¿Qué demonios estás haciendo?". Uno de los superintendentes de Bob estaba en la oficina con nosotros. Sonriendo ampliamente y con cara de burla, me dice: "Andy, no quiero que le reces al pato. Sólo quiero que le hagas tu pregunta". 
"¿En voz alta?", pregunté yo. 
"Así es, en voz alta", respondió Bob. En eso el superintendente añade, con la risa evidente en su cara: "Su nombre es Bob Jr.". Lo miré con cara de desagrado total. 
"Señor Pato", continué, "quisiera saber, si cuando uso un sujetador de tuberías, qué cosa mantiene la tubería del rociador de salirse del sujetador cuando la cabeza comienza a funcionar, causando que la tubería..." 
Justo a la mitad de formularle mi pregunta al pato, encontré la respuesta a mi pregunta. Volteo entonces hacia Bob y veo que asiente con la cabeza. "Ahora ya sabes, ¿no es cierto?". Le comenté la solución que había encontrado. "Así es. La próxima vez que tengas una pregunta, ven a mi oficina y dísela en voz alta al pato, no a mí. Si después de preguntarle a él no tienes la respuesta, entonces sí puedes preguntarme". 

¿Qué sucede? Al forzarnos a nosotros mismos a pensar en cómo podemos explicar nuestro problema de la manera más concisa, exacta y detallada posible, también nuestro cerebro se ve forzado a ver el problema desde varios ángulos, lo que en la mayoría de las ocasiones nos permite encontrar una solución que antes no veíamos. Al final lo más probable es que no tengamos que terminar la pregunta: ya sabemos cuál es el problema, y si no, al menos varios candidatos. Gracias a eso, ya no le quito (tanto) el tiempo a David, mi compañero en el trabajo, sino que pienso detenidamente las cosas, y si no encuentro la solución, imagino que quien está enfrente es un pato, y le hago mentalmente la pregunta.


Sin embargo, pienso mejorar. Tomaré este Yoshi que me regaló una ex-novia, me lo llevaré conmigo a trabajar, y será mi code-buddy. Espero levantar muchas cejas la próxima vez que le pregunte en voz alta al Yoshi cómo extender una clase de tipo de dato para Doctrine.








¿Alguna sugerencia de nombre para Yoshi?

lunes, 12 de marzo de 2012

Criptografía de llave pública

¿Alguna vez se preguntaron qué es todo ese asunto de las llaves públicas y privadas? Espero este video resuelva algunas de sus dudas.


Este post será el primero en una serie de posts respecto a seguridad informática. Próximamente:

  • Imágenes ejecutables.
  • ¿Por qué se bloquean las imágenes en los correos electrónicos?
  • Cómo crear una línea de comandos de php en un servidor remoto,
  • entre otras.
¡Disfruten!

viernes, 9 de marzo de 2012

Arquitectura REST para servicios web (con ejemplo en jQuery!)

Hola a todos!

En esta ocasión les platicaré un poco acerca de REST, una arquitectura para diseñar y construir servicios web. Este tema fué escogido debido a que fuera de los ámbitos de los desarrolladores, rara vez uno escucha los términos "arquitectura" al hablar de programación. No es lo mismo hablar de arquitectura de servicios como de  patrones de programación, o patrones de diseño. En próximas entregas hablaré un poco acerca de estos últimos.

Entonces, comencemos. Las siglas REST vienen de Representational State Transfer, y el término per se fué acuñado por Roy Fielding en su disertación de doctorado. Para no adentrarnos en los específicos de él, trataremos cómo implementarlo y por qué se ha vuelto tan popular desde su introducción.

REST plantea una nueva manera de modelar los servicios distribuidos, es decir, aquellos servicios que operan a través de una red, ya sea que se tengan recursos diferentes en máquinas diferentes, o que se trate de un servidor central y cierta cantidad de clientes. Históricamente, utilizando SOAP o algún otro tipo de servicios, se hacía lo siguiente:

Digamos que tenemos un blog, y queremos diseñar la interfaz del servicio al mundo exterior. Primeramente, definiríamos las acciones que se podrían llevar a cabo, por poner algunas:

  • getPostsList($tag, $category)
  • getUserPosts($userId)
  • getPostComments($postId)
en adelante. ¿Qué sucede si 6 meses después de que inicia operaciones nuestro blog queremos desarrollar una aplicación móvil, o simplemente nuestra interfaz de usuario cambia? Nos veríamos obligados a seguir las reglas del contrato que realizamos al inicio del desarrollo, es decir, a utilizar las funciones que mapean las acciones posibles del servidor a cada paso, lo cual representaría una tarea ardua de mantenimiento y actualización en cada cambio. ¿Y qué tal si requerimos cambiar algo en el servidor, aunque sea la firma de alguna función? Peor aún: tenemos que recorrer todo el código que depende de tal función, cambiarlo y verificar que cumple la nueva firma. En conclusión: tal vez parezca intuitivo hacer todo así, pero a la larga causará problemas de mantenimiento y escalabilidad.

En cambio, REST propone algo un tanto extraño: utilizar la definición del HTTP al máximo, y crear interfaces que expongan las recursos del servicio por medio de métodos estándar: es decir, adiós a los getters() y setters().

Para quienes no estén tan familiarizados con HTTP, basta recordar que existen dos tipos de métodos bastante usuales: GET y POST. Sin embargo, no son esos todos los que fueron definidos en el RFC, sino que existen otros dos cuya importancia ha sido marginal puesto que hasta hace poco, ningún navegador implementaba ese tipo de peticiones. Con la llegada de HTML5 y toda la funcionalidad extra que trae consigo, la presión sobre los desarrolladores de los navegadores fué mayor y por tanto podemos encontrar que la mayoría de los navegadores ya permiten realizar peticiones de esos tipos, si bien sólo por medio de XHttpRequest, mejor conocido como AJAX. Evidentemente, el hermano relegado de estos navegadores es IE, que no tenía pensado soportar dichas peticiones.

Como su nombre lo indica, GET, POST, PUT y DELETE hacen referencia a acciones que pueden realizarse con la información, y dado que son peticiones estándar, nos hace pensar en una arquitectura que explote al máximo esta funcionalidad: REST. 

Al repensar nuestro modelo de acuerdo a la arquitectura REST, vemos que no requerimos "funciones" para cada una de las acciones posibles dentro del servicio. Asimismo, ya no requerimos pensar en cómo exponer los recursos con los que contamos, puesto que todo esto se resuelve con HTTP:

  • Primero, pensamos en los recursos como objetos, como si fueran instancias de clases.
  • Después, vemos que con una sola dirección de acces (y diferentes peticiones) podemos realizar las operaciones básicas (CRUD) con ese objeto, lo cual simplifica mucho la interfaz.
En términos prácticos, esto se refleja en la siguiente estructura del blog:
  1. Se tendrán ciertas direcciones de recursos (URI) las cuales expondrán la información de dicho objeto.
  2. Mediante el tipo de petición, el servidor sabrá qué acción desea realizarse con el objeto, la realizará y le informará del resultado mediante los códigos de status HTTP al cliente.
Entonces, podemos, después de pensar un rato, que las entidades de las que se compone el blog son, a grandes rasgos, los usuarios, posts, comentarios, y tags. Fácil es ver que se requerirían 4 direcciones en nuestro servicio:
  1. midominio.com/blog/user/x
  2. midominio.com/blog/post/x
  3. midominio.com/blog/comment/x
  4. midominio.com/blog/tag/x
Ahora bien, eso sólo cubre una parte de los requisitos. Podemos realizar las acciones CRUD en cada una de esas entidades, pero nos resta saber de qué manera interactúan entre ellas. Por ejemplo, no tiene sentido hablar de un comentario a menos que sea a través de su autor o de el post en el que fué hecho. Eso provoca que se den los siguientes cambios:
  1. midominio.com/blog/user/x
  2. midominio.com/blog/user/x/comment/x
  3. midominio.com/blog/post/x
  4. midominio.com/blog/post/x/comment/x
  5. ...
Ahora, la cuestión de las peticiones: PUT, después de leer y leer discusiones, puede considerarse correcto su uso al querer hacer algo con información ya existente, es decir, información cuyo acceso conocemos. En otras palabras, su uso se presta perfectamente a un update, puesto que para realizarlo ya conocemos la identidad de la entidad a actualizar. POST puede utilizarse para muchas cosas, usualmente procesamiento de datos. Sin embargo, en el contexto REST, es comúnmente utilizado para crear una nueva instancia. DELETE, como su nombre indica, elimina la instancia del servidor, y GET sirve para obtener información sobre ella.

Para concluir entonces, les comparto un pequeño código en jQuery que ilustra la manera de trabajar:

$.ajax({
        type: "PUT",

        url: "http://midominio.com/blog/user/"+login,
        dataType: "json",
        data : {login : login,
                pass : pass,
                },
        success: function(datos) {

          alert("Datos recibidos! "+datos.login);
          //Recibimos datos como JSON: accedemos a sus propiedades como key.value
          $("div#json_results").append(datos.login);
        }
      });
    });

Básicamente, sucede lo siguiente: se realiza una petición AJAX a nuestro servidor en la dirección .../blog/user/x, que al ser PUT, actualizaría los datos con los que le enviamos, y nos podría regresar un array de datos en JSON, donde uno de ellos es el login actualizado (para verificar que todo salió a pedir de boca).

Para el lado servidor, pueden "simular" REST utilizando las variables de entorno como $_REQUEST, o utilizar alguno de los frameworks existentes. Existen varios que permiten trabajar de esta manera mucho más cómodamente, como Symfony (PHP, mediante un front-controller) y bakbone.js (JS, MVC de javascript para el cliente). Se realizan peticiones AJAX hacia los recursos del servidor, quien en caso de requerir regresar información, lo puede hacer de manera conveniente codificada como JSON o XML.

Finalmente, les dejo varias referencias que me fueron bastante útiles a la hora de aprender a hacer cosas "RESTful", como se le denomina a todo lo que cumpla esta arquitectura.

Happy Coding!


Referencias: