Text

Comandos útiles de npm


Pequeña introducción y algunos tips & tricks de npm aprendidos con el tiempo :)

npm init

Lo más básico. Deberíamos empezar un proyecto por aquí. Te pregunta una serie de cosas y te genera el fichero package.json para tu proyecto.

npm install <paquete> —save

Te instala un paquete y además añade la dependencia en tu package.json.

Por si alguna vez se nos olvida poner “—save” también podemos utilizar posteriormente require-analyzer que se encarga de poner al día el fichero package.json según lo que tengamos instalado en node_modules.

npm install <paquete> —save-dev

Como el anterior pero guarda la dependencia en devDependencies (dependencia en desarrollo) en vez de simplemente en dependencies.

npm install —production

Útil en el servidor para instalar las dependencias omitiendo las dependencias de desarrollo.

npm shrinkwrap

Genera un fichero npm-shrinkwrap.json que es un fichero que describe las dependencias de tu proyecto con los números de versión exactos que tengas instalados. Normalmente se intenta ser flexible con las dependencias al instalarlas (ej: un módulo afirma ser compatible con otro en sus versiones “1.1.x”), pero a la hora de instalar los paquetes en el servidor no queremos sorpresas. Esto lo conseguimos con el fichero npm-shrinkwrap.json. Si existe, el comando “npm install” se basará en este fichero en vez de en el package.json. Así de sencillo y útil.

npm outdated

Nos muestra qué paquetes que tenemos instalados tienen actualizaciones disponibles. Pero ojo, nos mostrará sólo aquellas actualizaciones que cumplan el rango de versiones definido en nuestro package.json. Así si por ejemplo dependemos de express “3.0.x” nunca nos indicará que haya una actualización a express “3.1.0” por ejemplo. Esto es interesante porque en principio debería evitar actualizaciones no compatibles hacia atrás con nuestro código.

Pero también nos interesaría saber si nos estamos quedando obsoletos. Para solucionar esto podemos usar npmedge que busca justamente las actualizaciones que no entren en el rango definido en el package.json. 

npm star <paquete>

Marca como favorito el paquete en npmjs.org. No tiene más utilidad que darle kudos a los desarrolladores del paquete.

Estos y algunos tricks más en NPM tricks

Tags: npm javascript
Text

Dos mentiras del mundo estartapil

Préstamos públicos como inversión privada

En ocasiones he visto anuncios en Loogic o incluso en Techcrunch de que ciertas startups recibían XXX miles de euros de inversión. Pero sin embargo una gran cantidad de ese dinero realmente eran préstamos públicos y no inversión privada. Vamos, que gran parte del dinero era dinero que las startups tenían que devolver, no dinero a fondo perdido.

Hay una modalidad de ayudas de distintas entidades públicas que se llaman préstamos participativos. Los más populares son ENISA y NEOTEC. Consisten en que te dan un préstamo, que tendrás que devolver, pero suele tener condiciones bastante ventajosas. Otra cuestión importante es que la startup debe presentar un plan y un presupuesto, y la entidad pública cubre una parte del presupuesto (un 70 - 85% normalmente) pero el resto lo tienen que aportar los socios. Es por tanto frecuente que para cubrir ese porcentaje restante se recurra a inversores privados (por ejemplo business angels). Pero lo que a veces también ocurre es que se comunica a los medios el presupuesto total como inversión privada, cuando realmente sólo ha sido un 15 - 30% de lo anunciado.

Adquisiciones de mentira: los acquihire

Otra mentira muy extendida se da sobre todo en empresas de EEUU. Anuncian que han sido compradas por una empresa grande, pero realmente no es una adquisición, sino que lo que ocurre es que la empresa grande contrata a los empleados de la otra compañía, pero puede ser que ni si quiera adquieran la tecnología ni los productos. Como ejemplo de esto tenemos Sparrow (supuestamente comprados por Google) o Acrylic (supuestamente comprados por Facebook).

Veamos por ejemplo Sparrow. El producto salvo por un par de pequeñas actualizaciones ha quedado estancado. No sale el logo de Google en el producto por ningún lado, no se ha “mergeado” con la app nativa de GMail en absoluto. Si vas a la Apple Store pone que Sparrow pertenece a “Sparrow by Google” y no a “Google Inc.” porque no está subida ni traspasada a la cuenta de Google en la Apple Store. Sin embargo cuando una empresa compra realmente a otra, pongamos el ejemplo de cuando Twitter compró Tweetie, inmediatamente cambia el logo, el branding, la imagen corporativa,… O por ejemplo en la última adquisición de Facebook, vemos cómo lo anuncian en su blog. ¿Hemos visto algún anuncio cuando “compraron” Acrylic? ¿Google dijo algo cuando “compró” Sparrow?

Estas adquisiciones se suelen llamar acqui-hire porque es una “adquisición de los empleados” pero no de la compañía. Los socios e inversores no reciben una suma millonaria por la compra de la compañía, sino que los empleados reciben un nuevo sueldo de la empresa “compradora”, pero se anuncia a bombo y platillo como una compra y no se dice nunca por cuánto (porque no hay compra real). Simplemente se “invita” a que la gente especule con la cantidad (que no existe). Aquí lo explican muy bien (aunque bastante duramente): Acqui-hire Is Just Another Way to Spell Failure

Tags: startup
Text

4 errores a evitar en JavaScript

Todos los lenguajes y herramientas tienen sus WAT? Pero más allá de casos extremos del lenguaje voy a exponer 4 problemas típicos en los que puedes caer si programas en JavaScript

1.- Variable Hoisting

Dado el siguiente código, ¿qué crees que sale por consola?

var someVariable = 'value1'
someFunction()

function someFunction() {
    console.log('someVariable', someVariable)
    var someVariable = 'value2'
}

¿Saldrá “value1” o saldrá “value2”? Pues no, sale “undefined”. En JavaScript resulta que el intérprete inicializa a “undefined” todas las variables que se declaran (ponemos “var”) en un scope al inicio de dicho scope. En nuestro caso si quitamos el “var” dentro de “someFunction” por consola aparecería “value1”, pero como la hemos declarado como variable dentro de ese scope (usando “var”) el intérprete la inicializa a “undefined” al inicio de ese scope (la función “someFunction”). Así que lo mejor es que declaremos las variables antes de usarlas (obvio, no?) y tener cuidado con los scopes.

Más información en JavaScript hoisting explained.

2.- Ojo al crear objetos con literales

Dado este código, ¿qué aparece por consola?

var key = 'foo', value = 'bar'
var obj = { key: value }
console.log('value', obj[key])

Tendría que salir “bar” no? Pues no, sale “undefined” porque “key” en la segunda línea es realmente un literal, y no el nombre de una variable. Es un literal aunque no vaya entrecomillado (que podría ir, de hecho en JSON es obligatorio). La solución es hacer lo siguiente: “var obj = {}; obj[key] = value”. Lo malo es que esto nos impide algunas declaraciones “inline” de objetos. Por ejemplo nos impide poder hacer:

var variable = getVariableName();
someFunction({variable: value})

Esto no funciona por lo mismo que antes, porque en la construcción del objeto “variable” es un literal.

3.- Ojo con las propiedades “ocultas” de un objeto

Supongamos que tenemos este código que simplemente dado un array de palabras (strings) cuenta cuántas veces aparece cada una:

var words = ['to', 'be', 'or', 'not', 'to', 'be']
var result = countWords(words)
console.log('result', result)

function countWords() {
    var count = {}
    for (var i = 0; i < words.length; i++) {
        var word = words[i]
		if (count[word]) {
			count[word]++
		} else {
			count[word] = 1
		}
	}
	return count
}

Resultado:

result { to: 2, be: 2, or: 1, not: 1 }

Perfecto, no? Bien, ahora vamos a poner una palabra más en el array de “words”. Añadimos “constructor”. Ejecutamos y el resultado es…

result { to: 2, be: 2, or: 1, not: 1, constructor: NaN }

WAT? ¿Qué ha pasado con “constructor”? Bien, pues la cuestión es que la declaración “var count = {}” no crea el objeto totalmente vacío, sino que hay una propiedad “oculta” de nombre “constructor” que apunta a la función que creó el objeto. En este caso el literal “{}” es como haber hecho “new Object()” y count.constructor apunta a dicha función Object. Bueno, estrictamente la propiedad “constructor” la posee el prototipo de “count”. Para más información podemos consultar la documentación de Mozilla al respecto. Bueno, ¿pero cómo solucionamos el asunto? Para solucionar nuestra pequeña función podemos hacer dos cosas.

  • O bien crear el objeto “count” con “var count = Object.create(null)” para crear el objeto sin prototipo (por eso pasamos null)
  • O bien cambiar el “if (count[word])” por “if (count.hasOwnProperty(word))” que chequea si el objeto posee esa propiedad sin tener en cuenta el prototipo del objeto.

4.- Bucles y closures

Es muy típico al empezar a programar en JavaScript equivocarnos en algo como esto:

for (var i = 0; i < 10; i++) {
    setTimeout(function() {
		console.log('i', i)
	}, 100)
}

Pensamos que por pantalla va a salir la secuencia 0, 1, 2,… y sin embargo sale el número 10 diez veces. WAT? El ejemplo usa la función setTimeout pero podría ser cualquier función asíncrona, o podríamos estar añadiendo un handler a un objeto del DOM, etc. El tema está en que el bucle itera todos los valores y cuando la función se ejecuta, el bucle ya ha terminado y la variable “i” tiene siempre el valor máximo para todas las ejecuciones de la función. ¿Cómo lo solucionamos? La solución más utilizada es generar una función intermedia que, como closure que es, guarde el valor en cada momento con otro nombre de variable:

function createLoopHandler(x) {
    return function() {
		console.log('i', x)
	}
}

for (var i = 0; i < 10; i++) {
	setTimeout(createLoopHandler(i), 100)
}

He hecho el ejemplo más verbose para que sea más legible, pero podráimos haber usado funciones “inline” (sin tener que declarar una función externa “createLoopHandler”. Bien, pues esto es lo más típico, pero también hay otra manera interesante que es usando la sentencia “with”.

var n = 10
for (var i = 0; i < 10; i++) {
    with({x:i}) {
		setTimeout(function() {
			console.log('i', x)
		}, 100)
	}
}

Esta última solución es muy clara y sencilla, pero habrá que tener cuidado porque la sentencia “with” tiene otras implicaciones. Más información sobre “with” en la documentación de Mozilla.

Actualizado: si estamos recorriendo una colección también podemos usar un iterador, como Array.forEach (que no está soportado en todos los navegadores) o jQuery.each

Tags: javascript
Text

JSONP y las curiosas respuestas JSON de Google

Hoy en día nos puede surgir la necesidad de usar desde una web un API / webservice externo. Tenemos el problema de que no podemos hacer llamadas AJAX a otros dominios. Bueno, sí con CORS, pero para eso el navegador lo tiene que soportar y el servidor destino también. Así que de momento no es suficiente siempre.

Pues JSONP surge de esa necesidad. Es un hack en toda regla, pero que funciona. No podemos hacer peticiones con XMLHttpRequest a otros dominios pero sí podemos generar dinámicamente tags <script> que apunten a URLs con otros dominios. Si el servidor a través de una URL nos devuelve un JavaScript como el siguiente: callback_function({“foo”:1234}) y previamente implementamos “callback_function” ya podemos hacer llamadas a webservices externos! Simplemente tenemos que implementar la función de callback, generar un tag <script> con dicha URL y esperar que la función sea llamada con los datos como argumento. Bien, pues eso es en esencia JSONP. Aunque tiene algunos problemas:

  • Sólo podemos hacer peticiones GET. Pero normalmente el servidor soporta algún parámetro para indicar qué método HTTP usar. Este parámetro suele llamarse “_method” y a la técnica se le suele referir como “method_override”.
  • No podemos responder con códigos HTTP de error o de redirección, ya que el navegador directamente ignorará el contenido de la respuesta y la función de callback no será llamada. Así que deberíamos incluir el código de error en la respuesta y devolver normalmente un código HTTP 200.

Estos problemas y la necesidad de poder definir en un parámetro de la URL el nombre de la función de callback implican que hacer que nuestros webservices sean JSONP-friendly requiera ciertos cambios. Más información en este estupendo artículo: Stripe.js and JSONP.

Defenderse de navegadores con bugs

A veces queremos lo contrario, no queremos que nuestra web sea llamada desde otros dominios. En principio no tendríamos que hacer nada ya que por AJAX no van a poder hacer peticiones desde fuera, y por JSONP si no generamos una llamada a una función y solamente devolvemos JSON, ese JSON se descargará, pero el contenido no se podrá gestionar por ninguna función de callback porque no la hay.

O no… Resulta que algunos navegadores cometen errores. Por ejemplo en versiones antiguas de Firefox se pueden sobreescribir la función Array, Object, Error,… y por tanto inyectar código que sería ejecutado al parsear cualquier estructura JSON, sin necesidad de llamar a funciones de callback. Así que aunque no implementemos nada para que otros consuman nuestros “webservices” los navegadores pueden contener errores y nuestros usuarios ser atacados por estos bugs.

Para evitar esto, algunos servicios como los de Google devuelven respuestas JSON que no son JSON del todo. Añaden “while(1);” o “&&&BLAH&&&” para impedir que el JSON se procese tal cual y sólo una llamada AJAX y no una llamada por tag <script> pueda procesar el resultado. Y como las llamadas AJAX están restringidas (mientras no usemos CORS), problema resuelto. La única pega es que nos añade un poco de complejidad tanto en servidor como en cliente. En servidor tendremos que devolver la estructura JSON modificada con ese prefijo que evita parsearse o procesarse correctamente, y en el cliente tendremos que descargar el contenido como un string, manipularlo para quitar el prefijo y luego parsearlo con eval() o con alguna librería.

Más información:

Text

Los programadores no necesitamos vanas promesas

Nuestra industria está plagada de modas. Todavía recuerdo la programación orientada a aspectos, la inyección de dependencias, la sobreutilización de XML, la arquitectura orientada a servicios, programación funcional,… Algunas de estas modas quedan en nada, y de otras quedan algunos posos que es la esencia útil después de quitarles polvo y paja.

Pues bien, de un tiempo a esta parte se oye un murmullo en forma de… promesas sobre todo en el mundo de JavaScript. Han surgido al menos uno, dos y tres frameworks, una especificación y otra especificación y tropecientos artículos de considerable extensión a favor y en contra. Incluso algunos básicamente pregonan que la gente no se está enterando de qué va esto. Qué locura. Con tanta agitación me he querido enterar bien y después de leer y leer y de informarme todo lo posible llego a la conclusión de que las promesas no me aportan nada nuevo y me hacen cambiar mis APIs y ¡hasta me hacen escribir más código!

¿Pero de qué va esto de las promesas?

Para explicarlo me voy a saltar a otro lenguaje donde creo que sí son útiles. Me voy a Java un momento pero casi cualquier otro lenguaje valdría. Supongamos que queremos descargar contenido de dos páginas web que devuelven texto plano y lo queremos concatenar. Lo común en un lenguaje como Java donde las APIs suelen ser síncronas sería hacer algo así (voy a obviar todo el tiempo la gestión de errores por brevedad):

String a = descargarContenidoWeb("...");
String b = descargarContenidoWeb("...");

// hacer algo con a y b
String c = a + b;

Esto está bien, pero es mejorable porque como las llamadas son bloqueantes (esperan) la segunda descarga sólo empieza cuando la primera ha terminado. Veamos cómo sería usando Future (la forma estándar de usar promesas en Java). Reimplementaríamos el método descargarConteniedoWeb internamente para que devolviese una promesa y luego lo usaríamos así:

Future<String> a = descargarContenidoWeb("...");
Future<String> b = descargarContenidoWeb("...");

// hacer algo con a y b
String c = a.get() + b.get();

Nada más llamar a descargarContenidoWeb el contenido se empieza a descargar, pero la ejecución no se bloquea y la segunda descarga también se empieza a ejecutar en segundo plano a la vez que la primera. Como el contenido se está descargando y todavía no podemos viajar al futuro, no se devuelve un String con el contenido, sino una promesa. Pero tarde o temprano queremos obtener finalmente el contenido. Para eso está el método get() de las promesas. Este método chequea si la descarga ha terminado, y si no ha terminado bloquea hasta que termine. Con el get() estamos bloqueando, pero las descargas ya se han lanzado a la vez en segundo plano. Sencillo y útil, no?

Ahora volvamos a JavaScript. En JavaScript no hay APIs bloqueantes (salvo muy puntuales excepciones). Las funciones que pudieran ser bloqueantes en vez de devolver una variable reciben un callback como parámetro que será llamado cuando la operación termine. Esto lo habremos visto muchas veces si hemos usado JavaScript en el frontend (con jQuery por ejemplo) para hacer AJAX o para escuchar eventos HTML, etc. Así pues una llamada a la función descargarContenidoWeb tendría que ser una cosa así

descargarContenidoWeb('...', function(err, contenido) {
	// ...
})
console.log('Esto ese ejecuta mientras se descarga el contenido')

Como la función no bloquea podemos llamar a la función dos veces consecutivas sin anidación, para descargar los contenidos en paralelo.

descargarContenidoWeb('...', function(err, a) { ... })
descargarContenidoWeb('...', function(err, b) { ... })

Listo, ya estamos descargando los contenidos en paralelo. Pero… ahora tenemos dos funciones de callback y necesitamos hacer algo cuando terminen ambas descargas. ¿Cuándo sabemos que las dos han terminado? ¿Dónde ponemos ese código? ¿Cómo nos las arreglamos? Bien, veamos una forma rápida de gestionarlo

var _a = null, _b = null
function finalizar() {
    if (_a && _b) {
        var c = _a + _b
}
}
descargarContenidoWeb(function(err, a) {
_a = a; finalizar()
})
descargarContenidoWeb(function(err, b) {
_b = b; finalizar()
})

Mmmm… Solucionado, pero poco elegante y poco legible. ¿Se puede mejorar? Sí, con un callback handler como async (se puede usar tanto en nodejs como en el navegador; en nodejs es el segundo módulo más popular). Con async nuestro problema podría solucionarse así:

var urls = ['...', '...']
async.map(urls, descargarContenidoWeb, function(err, results) {
    var c = results[0] + results[1]
})

La función map() recibe un array de elementos y una función que los procesará. Finalmente devuelve un array de resultados. Así de sencillo. 

¿Y qué hay de las promesas? Bien, pues con promesas en vez de usar los callbacks de toda la vida tendríamos que reimplementar la función descargarContenidoWeb para que devolviese una promesa. Después usarla con Q sería una cosa así:

var a = descargarContenidoWeb('...')
var b = descargarContenidoWeb('...')
Q.allResolved([a, b]).then(function (promises) {
    var c = a.valueOf() + b.valueOf()
})

¿Queda bien, no? Sí, pero no veo ninguna mejora, incluso ocupa más código, y hemos tenido que reimplementar la función y añadir un framework externo que tendrá que usar tanto quien implementa la función como quien la usa, y el nivel de anidamiento es el mismo, y…

…Y además librerías como async hacen muchísimas más cosas sin tener que reimplementar nada. En nuestro ejemplo imaginemos que tenemos mil URLs en vez de dos. Nos interesaría no descargar las mil de vez, sino ir descargando como mucho un número máximo de items a la vez. Pues bien con async es tan sencillo como usar mapLimit() en vez de map(). Simplemente tiene un argumento más en el que le decimos el máximo de items a procesar a la vez. ¡Voilá! Yo estoy encantado, de verdad que no he encontrado ninguna otra combinación de lenguaje o framework donde fuera tan sencillo hacer cosas en segundo plano de forma tan simple y flexible. Os invito a echar un vistazo a todas las funciones y ejemplos del módulo async.

¡Es más! Si tenemos un nivel medio de JavaScript en apenas 25 líneas de código podemos hacer nuestro micro-callback-handler (lo he llamado collector) sin necesidad de usar una librería externa como async. El código queda así:

var c  = collector()

descargarContenidoWeb('...', c.bind('a'))
descargarContenidoWeb('...', c.bind('b'))

c.collect(function(errors, results) {
    var c = results.a + results.b
})

Lo único que hace bind() es crear una función de callback que guardará el resultado con el nombre que le damos y finalmente hay un callback para recolectar todos los resultados. Super sencillo y de nuevo una forma simple y legible de hacer lo mismo y sin necesidad de modificar la implementación interna de la función.

Mis conclusiones

  • Las promesas son útiles en un lenguaje con APIs síncronas (ej: Java) porque ayudan a hacer cosas en paralelo, pero en un lenguaje con APIs no bloqueantes pierden utilidad porque ejecutar cosas en paralelo es el comportamiento por defecto. Con la ayuda de un callback handler además podemos hacer virguerías.
  • Un callback handler permite hacer todo lo que podemos hacer con las promesas y más. Y además sin tener que cambiar las implementaciones de nuestras funciones para usar promesas.
  • Las promesas no resuelven el callback-hell o pirámide de la muerte. La pirámide de la muerte se resuelve muy fácilmente: dividiendo el código en funciones.

Finalmente he dejado unos ejemplos comparando el uso de una librería de promesas versus la librería async. Se compara el uso de una función aislada y la ejecución en paralelo de dos funciones.

Y después de esta chapa… ¿Creéis que las promesas en JavaScript son una moda más? ¿Creéis que son útiles? ¿Merecen la pena? ¿Me estoy dejando algo?

Text

Querido programador, vas a recibir la visita de 3 fantasmas

En la vida de todo programador llega un momento con en el que te topas ante un problema que no te esperabas, y aparentemente es sencillo de resolver, pero al final te puede llevar horas o días resolverlo. A eso me refiero con recibir la visita de un fantasma. Me gustaría hablar de los 3 fantasmas más comunes en la vida de todo programador.

1.- Codificaciones de caracteres

Como dice Joel Spolsky, hay algo que todo programador debería saber:

There Ain’t No Such Thing As Plain Text

El texto en la programación no es más que un puñado de bytes. Y ese puñado de bytes si no sabemos con qué codificación de caracteres ha sido creado estamos perdidos.

Cada protocolo o formato de archivo define una o varias formas de definir la codificación de caracteres que se va a usar: cabeceras (ej: HTTP Content-Type), metatags (HTML), codificaciones por defecto,…

MySQL puede ser una locura particularmente. Tiene infinidad de variables relacionadas con el charset a utilizar: character_set_client, character_set_results, character_set_server, character_set_database, character_set_system, character_set_filesystem. Pero es que además podemos definir un charset a nivel de columna, un charset a nivel de tabla,…

Pero bueno, una vez tenemos todo configurado ya no todo funcionará como la seda ¿no?. Bueno, pues resulta que no, que los lenguajes de programación, navegadores, etc. como todo software tiene bugs o decisiones de diseño que también afectan al tema de las codificaciones de caracteres. A modo de ejemplo:

  • JavaScript internamente usa una representación denominada UCS-2 que provocó problemas (ya solucionados) en V8 por ejemplo al manejar caracteres emoji.
  • Internet Explorer <= 8 porque le da la gana en algunas circunstancias no envía los formularios por UTF-8 aunque la página haya sido servida como UTF-8. El workaround es mandar un caracter que sólo exista en unicode. Por eso a veces vemos en algunas páginas en la URL un parámetro utf8=✓ o un muñeco de nieve ☃.
  • Java decidió que nunca resolvería un bug sobre UTF-8 relacionado con la primera secuencia de bits en un string unicode que indica el encoding (UTF8, UTF16,…). El workaround que propuso Sun Microsystems fue “parsealo tú”.
  • Como último ejemplo comentar que PHP 6 que se supone será PHP 5 + Unicode ha sido abortado sin todavía noticias de cuándo será retomado por las complejidades internas para soportar unicode en todo el lenguaje (cadenas, identificadores de variables, nombres de funciones,…).

2.- Fechas, horas y zonas horarias

Al igual que un string no es más que un puñado de bytes y tenemos un problema si no sabemos en qué codificación de caracteres está, con los datetimes ocurre algo parecido. Si tenemos un datetime (ej: “01-01-2012 00:00:00”) y no sabemos en qué zona horaria fue creado, tenemos un problema. Si esa fecha viaja por un webservice desde España a un servidor en el datacenter de Amazon de Irlanda (una hora menos que España) ¿Cómo lo parseará el cliente? ¿Cómo lo parseará el servidor?

Personalmente prefiero guardar siempre un número, un unix time y a la hora de mostrarlo al usuario elegir una zona horaria (la del navegador, la de alguna configuración del usuario, etc). Pero para mí mostrar una fecha en formato humano es siempre un problema de la capa de presentación, no de la capa de datos de la aplicación.

En casi todo lenguaje de programación que se precie tendrás una manera de representar fechas usando una u otra zona horaria. Sin embargo algún lenguaje de programación no tiene soporte para esto. I’m looking at you, JavaScript. En JavaScript puedes obtener un offset respecto a UTC (olvida GMT). ¿Es suficiente guardar ese offset a modo de zona horaria? Pues no, porque el offset en una misma región del mundo puede cambiar en el tiempo por dos razones:

A partir de este problema he conocido que hay una base de datos de zonas horarias con todos los cambios de hora que ha habido históricamente en todas las regiones del mundo. Esta base de datos contiene ficheros de texto con “reglas” para interpretar correctamente las zonas horarias. Y unos tipos muy majos se han encargado de hacer una librería en JavaScript que procesa esta base de datos: timezone-js.

3.- Expresiones regulares

Se suele decir que si tienes un problema y lo resuelves con expresiones regulares, enhorabuena, ahora tienes dos problemas. Son una gran herramienta pero son en ocasiones difíciles de manejar. Sólo hay que ver lo complicado que es validar correctamente direcciones de email con expresiones regulares o los intentos de parsear HTML con expresiones regulares (llegando a la conclusión de que no se puede). Incluso algo tan fácil como buscar URLs en un texto puede ser más complicado de lo que parece.

4.- El cuarto jinete de la Apocalipsis: la concurrencia

Esta es la madre del cordero de todos los fantasmas. Hay muchos contextos en los que simplemente puedes obviar la concurrencia. Si programas en JavaScript la puedes obviar completamente, si trabajas en el backend con un framework/contenedor web sencillo también la puedes obviar en la mayoría de ocasiones. Pero si haces aplicaciones nativas (móviles o de escritorio) ya puede ser que empieces a leer sobre una cosa que llaman “main thread” que se encarga de pintar la interfaz y que no puedes bloquear con operaciones costosas porque tu aplicación se queda congelada. Oirás hablar de bloqueos, semáforos, deadlocks, operaciones atómicas, queues, asincronismo, pools de threads,… ¡Bu! Asusta, verdad?

La concurrencia es especialmente dura porque es difícil de encontrar errores relacionados con ella, reproducirlos y solucionarlos. Recuerdo en una empresa en la que había tests que a veces pasaban con éxito y otras veces no. Y los datos iniciales eran siempre los mismos. El problema era la sincronización de varios hilos de ejecución.

Estoy preparando un extenso artículo sobre concurrencia. Cuando esté listo espero que lo disfrutéis. Avisaré :)

En fin… aquí termina esta recopilación de pequeños / grandes problemas que todo programador se encuentra a su largo de su vida profesional. A veces parecen cosas sencillas, pero realmente tienen mucha miga. ¿Me he dejado algo? ¿Cuáles son tus fantasmas?

Text

Las guerras santas en los mundos de REST

Hace tiempo yo tenía asumido que REST era una cosa sencilla que no requería mucha explicación para un programador y que no había mucho más que hablar o debatir. Sin embargo en los últimos años he visto muchos debates entorno a qué es REST y qué no es. Hay posiciones encontradas y hay mucha miga. Voy a resumir algunos de los temas que surgen en estos debates.

Verbos HTTP

Hay opiniones enfrentadas sobre por ejemplo cuándo usar PUT, POST y PATCH. Tradicionalmente yo había visto usar POST para crear recursos/objetos y PUT para actualizarlos. Bueno, pues resulta que las más estrictas interpretaciones de las semánticas de los verbos HTTP aconsejan usar PUT para modificar o crear “recursos” si se conoce la URL final del recurso, POST si se desconoce esta URL, y PATCH para actualizaciones parciales. ¿Qué es eso de conocer la URL final? Muy sencillo, la URL final no la sabes si al crear el recurso el servidor le asigna un id que tú no le has mandado (ej: al hacer insert en una base de datos relacional la clave primaria es un autoincremental). En ambos casos la URL final para obtener el recurso suele ser GET /tipo-recurso/id-recurso, pero en un caso el id lo asigna el servidor y en otro viene dado por el cliente. Según esto habría que usar PUT en un caso y POST en otro.

Pero… a mi realmente esto me parece una discusión sin mucha trascendencia. Qué mas da usar uno u otro. Qué importa hacer esas diferenciaciones semánticas…

URLs

Todos estamos de acuerdo en que ciertos tipos de URLs son horribles y que hay ciertos tipos de patrones que es conveniente seguir. Los más académicos sugieren no usar verbos en las URLs, porque la acción viene dada según el método HTTP usado. Por ejemplo GET /user/123/show sería incorrecto porque “show” nos sobraría. Pero qué pasa si necesitamos verbos adicionales? Por ejemplo hacemos una aplicación que hace “checkin” o “like”? Bueno, pues suele haber dos aproximaciones:

  1. Que sea una modificación de una entidad existente. Por ejemplo un “like” modificaría una entidad existente “item” (o lo que sea) incrementando el número de “likes” recibidos. Así que se haría un PATCH a /item/1234 Pero para mi esto es incompleto ya que la acción también debería modificar al usuario, guardando ese like para que el usuario no pudiera volver a hacer like en ese objeto.
  2. Que sea la creación de un objeto. Es decir, que el “like” sea un objeto en sí mismo por lo que haríamos un POST /like De todas formas seguimos con la cuestión anterior, estamos creando un objeto pero en el servidor se están actualizando colateralmente otros dos.

Personalmente no le doy mucha importancia tampoco a este tema. Al final es casi más un asunto estético que otra cosa.

Versiones del API y formato de respuesta

Este es otro motivo de controversia. Es típico que la versión del API vaya en la URL o bien en parte del path (ej: GET example.com/v1/foo) o como sudominio (ej: GET v1.example.com/foo ).

Si el API soporta varios formatos de respuesta (ej: XML y JSON) también es frecuente que se indique en la URL, a veces de forma opcional devolviendo por defecto uno de los formatos soportados. Ej: GET /foo.xml, GET /foo.json, GET /foo (devolvería el formato por defecto)

Pero los más académicos afirman que esto es incorrecto porque cada recurso tendría que tener su URL única. Pero entonces ¿dónde indicamos la versión del API y el formato de respuesta que queremos obtener? Pues hay una tendencia a que esto se defina en la cabecera estándar HTTP “accept” con un mime type propio. Ejemplo:

Accept: application/vnd.github.beta+json

Ejemplo sacado del API de GitHub. El servidor responderá además con una cabecera Content-type con el mismo mime-type.

Creo que esto semánticamente está muy bien, pero complica las cosas innecesariamente sólo por intentar mantener el purismo del asunto. Tener que cambiar cabeceras HTTP puede no ser posible (dependiendo del API http que usemos o si necesitamos usar JSONP), es más difícil de depurar y también puede producir problemas en librerías de HTTP porque no reconocen los mime-types.

Hypermedia APIs, HATEOAS y otras hierbas

En mi opinión todo lo anterior son temas menores, cosas que de una forma u otra no cambian demasiado las implementaciones de servicios o clientes REST. Ahora viene cuando a mi me dejan con el culo torcido ¿Tu API REST devuelve un JSON que tú mismo has definido? ¿Tu API la has creado sobre una librería/framework web? Pues según los más fundamentalistas ¡no eres RESTful! ¿Cómo? Pues sí señor, según el señor que más sabe de esto las APIs REST deberían ser hipertext-driven y que…

A REST API should not be dependent on any single communication protocol

Vamos, que si tu implementación está ligada a HTTP ya no eres RESTful. ¿Cómo te quedas?

Pero bueno ¿qué es eso de hipertext-driven? Pues básicamente que deberías devolver HTML o algún lenguaje que tenga links y forms. Aquí lo explican muy bien y muy brevemente. Para ser RESTful tu API debe ser navegable. Vamos, que haya links, no indicar ids en las respuestas sino URLs completas, e indicar las relaciones entre recursos.  Todo ello supuestamente con la intención de que las APIs sean autodescubribles y autodocumentables y que hubiera hipotéticos clientes REST que tuvieran una consola para poder navegar por el API como quien navega por internet… Podéis ver From REST to HATEOAS que aporta más información.

La lectura más fundamentalista de este tema indicaría que hay que devolver HTML, que ya es un lenguaje que define links y forms. Pero bueno, supuestamente también podríamos usar XML gracias a los estándares XLink y XForms pero en JSON se necesitan cosas como HAL u otros estándares como Siren o Collection+JSON. Aquí podéis ver un ejemplo sacado del borrador de especificación del JSON Hypertext Application Language (HAL):

{ ”_links”: { ”self”: { “href”: “/orders/523” }, ”warehouse”: { “href”: “/warehouse/56” } }, ”currency”: “USD”, ”status”: “shipped”, ”total”: 10.20 }

Pero ojo, irónicamnete HAL no incluye soporte para “forms” sino tan solo para “links”.

En fin… qué más decir. Personalmente soy muy escéptico de la utilidad de añadir tanta complejidad y reglas y me parece que están convirtiendo a REST en el nuevo SOAP. Prefiero soluciones más livianas y pragmáticas y no tan académicas. Vamos, ¡lo que ha venido siendo REST hasta ahora!

Para terminar os dejo una parodia de estos fundamentalismos a la hora de crear APIs RESTful. Escuchadla y veréis lo ridículo de todo este asunto.

Tags: rest api
Text

Google: estos son mis principios; si no le gustan, tengo otros

Mi compañero del metal, David Bonilla, diagnostica en su última bonilista un trastorno bipolar en el internet patrio. Se debe a las reacciones al cierre de Google Reader. Según Bonilla no deberíamos criticar esta maniobra porque es una decisión económica que hay que respetar. Que Google habrá considerado que no le es rentable y por eso se cierra y punto.

Bien, pues yo sí que creo que hay bastante que criticar. Para empezar no creo que Google haya intentado si quiera rentabilizar Reader. Google se embarcó en decenas de servicios sin pretensiones de monetizarlos. Todo lo hacía al parecer por el interés general, por un internet más abierto, etc. Luego llegó la crisis y vio que otras compañías le adelantaban por la derecha (Facebook, Apple) y entró en pánico. Empezó a cerrar servicios y a empezar a cobrar en otros (ej: Google Maps). Hasta ahí me parece estupendo. Si un servicio no te es rentable lo intentas monetizar, y si no puedes lo cierras. Fantástico.

Sin embargo Reader no lo ha intentado si quiera monetizar. ¿De los millones de usuarios que tiene no estaríamos dispuestos a pagar una pequeña cuota para convertirlo en algo rentable? Seguro que sí, yo ya estoy pensando en migrar a Newsblur y pagar. Los que usamos Reader no somos usuarios cutres como los que no quieren pagar Whatsapp. Yo uso Reader y además he pagado por clientes de Reader en 3 de mis dispositivos. Y pagaría una mensualidad sin problemas.

Google no ha intentado monetizar Reader. ¡Si ni si quiera ha hecho cambios significativos en los últimos años! (Salvo cambiar el look and feel para homogeneizarlo con el resto). Lo que ha hecho Google es comerse sus propios principios. Google durante años ha sido el abanderado de los estándares abiertos, del internet abierto, etc. Y de repente ha dejado de pensar así. Hace un año Sergey Brin se quejaba así de Facebook y Apple (los nombraba explícitamente en otro momento): 

“There’s a lot to be lost,” he said. “For example, all the information in apps – that data is not crawlable by web crawlers. You can’t search it.”

Google’s Sergey Brin en una entrevista en The Guardian

Y ahora Google ha pensado que si los demás no son abiertos él tampoco tiene porqué serlo. Ha visto que si la gente dejase de usar formatos como RSS usarían más Google+, y ya está, y dejémonos de un Internet abierto. Ahora a Google le importa su Google+ y nos lo está metiendo hasta en la sopa. Ha montado su propio restrictive walled garden. A ver por ejemplo cuánto tiempo dura blogger o cuánto tiempo tarda en ser fagocitado por Google+.

¿Están en su derecho? Perfectamente. Pero también perfectamente podemos criticarlo por ello. Es como cuando una leyenda del rock empieza a hacer música comercial. Ganará más dinero o no, pero por supuesto que podemos criticarlo. O como si una tienda de productos ecológicos empezase a vender repostería industrial a paladas. Por eso pienso que Google ha tirado sus principios por el retrete.

Quizá siempre ha tenido los mismos principios, pero camuflados. Quizá sólo defendía un internet libre y abierto porque es necesario para su buscador, y no lo defendía por ningún principio o cultura de empresa.

Pero bueno, a mi no me molesta que una empresa quiera ser más cerrada para mejorar su cuenta de resultados. Lo que me molesta es que venda una imagen de apertura que finalmente no es.

No obstante es triste ver a una empresa hacer este tipo de maniobras. Desgraciadamente estamos muy acostumbrados últimamente a ver empresas cerrar productos y servicios (Reader, Posterous, OpenSolaris,…) dejando a sus usuarios desamparados y ver también otros servicios ser cada vez más y más cerrados (Twitter, Netflix,…).

Tags: reader google
Text

JavaScript dominará el mundo

Hace ya unos años Jeff Atwood enunció la “Ley de Atwood”

Any application that can be written in JavaScript, will eventually be written in JavaScript.

Es evidente que a día de hoy la programación web está extendidísima y las aplicaciones web han sustituido a muchísimas aplicaciones de escritorio. Además también se hacen multitud de aplicaciones para smartphones y para tablets con tecnologías web.

No obstante el título de este post es totalmente sensacionalista intencionalmente :). Creo que las aplicaciones nativas tanto de escritorio como para smartphone y tablets por supuesto seguirán existiendo y serán la mejor opción en muchos casos.

No obstante es increíble las cosas que se están haciendo en JavaScript. A día de hoy programas como Emscripten han permitido migrar programas escritos en C/C++ a JavaScript! Entre otras cosas han portado parte de Qt. Personalmente me parece increíble.

Pero hay vida más allá de HTML

Jeff Atwood habla de web programming cuando enunció su ley. Sin embargo JavaScript ha evolucionado más allá de ejecutarse en un navegador. A día de hoy hay muchos contextos en los que podemos usar JavaScript sin HTML, sin un DOM, sin CSS, etc. Pondré sólo algunos ejemplos:

  • Nodejs es un framework usado sobre todo para programar aplicaciones de red, aplicaciones web, etc. en JavaScript. Si no lo conoces… ¡deberías!
  • Appcelerator es un framework para hacer aplicaciones para smartphones multiplataforma. Se diferencia de otros como Phonegap o Sencha en que no hay HTML, DOM, CSS. Es JavaScript interpretado que crea componentes gráficos nativos. Otro framework similar es trigger.io
  • Recientemente se ha anunciado que GNOME elige JavaScript como lenguaje preferente a la hora de desarrollar aplicaciones.
  • Ejecta, es una librería para iOS que implementa la API de canvas de HTML y un API de audio. Las llamadas a la API de canvas se convierten a llamadas OpenGL directamente. El canvas “viene dado” por la librería, no hay HTML de por medio realmente. La librería usa directamente el intérprete de JavaScript que interpreta directamente el código, sin ningún HTML de por medio.
  • También hay una tendencia, aunque más de afición que de algo profesional, de programar hardware en JavaScript.
  • Editado: ¡no nos olvidemos de las bases de datos con JavaScript integrado! Como CouchDB, MongoDB o RethinkDB.

El futuro es prometedor

Cada vez hay más plataformas y más movimiento entorno a JavaScript. Si no te gusta el lenguaje además no importa, puedes elegir entre otros lenguajes diseñados para ser compilados a JavaScript como Dart, TypeScript o CoffeeScript.

Finalmente comentar que en el futuro también podremos programar JavaScript “de bajo nivel” con asm.js. Se trata de un subconjunto de JavaScript que permite al intérprete hacer optimizaciones de bajo nivel importantes. Y dado que es un subconjunto del lenguaje, es totalmente compatible con intérpretes que no lo soporten. Firefox tiene planes para soportarlo. ¡Y espero que V8 lo implemente más pronto que tarde! (V8 es la máquina virtual que incluye Chrome y usa Nodejs)

Tags: JavaScript
Text

Elige una función hash

Las funciones de hash o de resumen de mensaje nos permiten verificar la integridad de un mensaje. Para este cometido se suelen utilizar SHA en alguna de sus variantes (SHA1, SHA256) o MD5. Son funciones rápidas y siempre devuelven el mismo resultado a partir del mismo mensaje. Su uso es muy frecuente. Por ejemplo en casi todos los repositorios de software tienes los checksums de lo que te vas a descargar para verificar su integridad (ejemplo). Y en git los nombres de los commits son hashes SHA1 que sirven para verificar también la integridad de los mismos.

Dada su dificultad de calcular el mensaje a partir del hash estas funciones también sirven para evitar tener que guardar passwords. Si guardamos el hash evitamos un robo masivo de passwords si alguien accede a nuestra base de datos. En vez de ello comprobamos que el hash de lo que nos da el usuario concuerda con lo que hay en la base de datos y listo. No tenemos necesidad ni de “ver” el password. Pero para esto SHA1 y MD5 son malas funciones de hash. Por un lado porque siempre dan el mismo resultado a partir del mismo mensaje de entrada. Por lo que si vemos que dos usuarios tienen el mismo hash ya podemos averiguar que tienen el mismo password. (Aunque bueno el siguiente paso sería usar salts). Y por otro lado son malas en este caso porque son rápidas, así que un atacante tendrá fácil la tarea probar muchos miles de passwords. Además no le podemos añadir lentitud fácilmente. Podemos calcular el hash del hash del hash… en un bucle de cientos o miles de iteraciones para hacerlo más lento, pero también tenemos que previamente saber nosotros cuántas veces queremos iterarlo para posteriormente verificar los logins de los usuarios, y si un día queremos cambiar el número de iteraciones tendríamos que mantener la compatibilidad hacia atrás con los ya calculados…

Para este caso último tenemos otros algoritmos de hash mejores: bcrypt, scrypt, o PBKDF2, que son algoritmos de hash adaptativos. Es decir, podemos hacerlos más lento fácilmente sin ninguna complejidad. Normalmente le pasaremos un “factor” como número entero a la función que cuanto más alto sea hará que la computación sea más lenta, y la función de comprobación es suficientemente inteligente para comprobar hashes calculados con cualquier “factor de lentitud”.

Length extension attack

Por último, ojo con “Length extension attack”. Es un problema de algoritmos como SHA1 y MD5. Lo que ocurre es que por el modo en el que funcionan se puede probar a ir añadiendo contenido a la derecha a un mensaje y en algún momento podrá dar el mismo hash que el mensaje original. Para esto tenemos las funciones HMAC que lo que hacen es combinar una función de hash con una clave y hacer varias operaciones para evitar estos ataques. Dado que una función HMAC usa una función de hash internamente encontraremos que hay varias combinaciones: HMAC/SHA1, HMAC/SHA256,…

Más información:

Tags: seguridad