Archivo de la etiqueta: web

Adaptación automática de páginas web en dispositivos móviles utilizando RWD

A estas alturas toda organización o empresa que se precie tiene presencia digital, como se suele decir, si no estás en Internet no existes. Para construir una imagen de marca es necesario tener al menos una web propia y con dominio propio (los hosting gratuitos están muy bien para experimentar pero a nivel profesional daría una imagen similar a ir al trabajo en pijama). En estos últimos años han aparecido nuevos dispositivos capaces de acceder a la web (smartphones,tablets,smart tvs,etc), cada uno de ellos con distinta resolución y tamaño de pantalla.

graphResponsive

Como es de suponer, según el dispositivo empleado variará la visualización y experiencia de usuario (aunque a priori todos sean capaces de acceder al mismo contenido), por ello es necesario que nuestra web se adapte de la mejor forma posible utilizando el llamado Responsive Web Design (RWD). En este tutorial se va a mostrar como hacer una web responsive y de paso se incluirá una librería jQuery para simular un elemento propio de plataformas móviles.

 

Responsive Web Design

El RWD o Responsive Web Design es un enfoque de diseño cuyo objetivo es que cambie dinámicamente la forma de visualización de una página según las características del dispositivo que acceda, para conseguirlo se trabaja con la capa de presentación, es decir, sólo es necesario modificar las hojas de estilo CSS, por lo tanto el propio diseñador puede realizar el trabajo sin afectar al resto de capas.

Antes de su aparición, se creaba una versión móvil para mejorar la experiencia de usuario en caso de que el acceso fuera desde un dispositivo diferente a un ordenador, entonces, ¿para qué aplicar el RWD? Las ventajas de este enfoque son varias, principalmente que no se duplica contenido (y por tanto no penaliza el SEO) y que no es necesario modificar la lógica de negocio ni la información almacenada (ya que sólo se actúa sobre la capa de presentación), en consecuencia se ahorra bastante trabajo y se simplifica el diseño, mejorando sensiblemente la mantenibilidad. Como contrapartida es necesario enviar más datos en cada petición, pero si la página está bien diseñada el incremento es perfectamente asumible.

El libro de referencia para entender este diseño es «Responsive Web Design», donde Ethan Marcotte explica su historia, los principios que se deben seguir y cómo aplicarlos. Según este libro se deben cumplir varias condiciones para que una web sea responsive:

– Debe tener una estructura flexible, donde se deben evitar los tamaños fijos (ya sea en píxeles, pulgadas,etc) usando tamaños relativos (porcentajes,em’s) en su lugar. El resultado será que el tamaño de los elementos no será siempre el mismo, sino que se adaptará a la resolución de la pantalla donde se muestra.

– Los Elementos multimedia deben ser flexibles, de forma similar al caso anterior, se pretende que las imágenes, videos y el resto de elementos multimedia sea capaz de adaptar su tamaño en función de la resolución de la pantalla donde se renderiza. Hay que tener en cuenta que algunos navegadores antiguos (principalmente versiones de IE6 y anteriores) no son compatibles con atributos que se utilizan para lograr esta flexibilidad, por lo que se deben tener alternativas si se prevé que un porcentaje considerable de visitantes usen cualquiera de esos navegadores (IE6 viene incluido por defecto con Windows XP, el cual sigue presente en muchos equipos a pesar de que Microsoft ha dejado de darle soporte desde principios de este año)

– Se usan Media Queries (las cuales están disponibles desde la especificación de CSS3) cuya función es seleccionar qué estilos se aplican a la página. Cada Media Query tiene un conjunto de estilos que se aplicarán siempre que su Media Type (el tipo de medio puede ser una impresora, tv, etc) encaje con el dispositivo y si se cumplen las condiciones que se le han asignado (como que tenga un ancho máximo, tenga una determinada orientación, etc). En la práctica el Media Type no es muy útil para los dispositivos actuales, sino que se emplean las condiciones adicionales para adaptarse a los dispositivos, por ejemplo, si queremos que se adapte a un móvil de pantalla FullHD será necesario al menos una Media Query que tenga en cuenta el ratio, mientras que si queremos adaptarnos a un móvil de gama baja deberíamos usar al menos una Media Query que filtre por una resolución baja.

Aún falta un último detalle para que la página se muestre completamente adaptada a la pantalla, y es la inclusión de la metaetiqueta viewport a las páginas donde se pretendan aplicar los estilos. Su función es encargarse de configurar a qué escala se mostrará la página y asignarle la anchura donde deberán encajar todos los elementos de la página. Fue creada por Apple para su navegador Safari a fin de mejorar la visualización de las páginas web al utilizar el iPhone, pero con el tiempo otros navegadores lo han copiado tambien le han dado soporte.

 

Ejemplos sin RWD

Ahora que ya sabemos más acerca de RWD voy a analizar algunas páginas que no lo aplican, con lo que saldrán a relucir las inconvenientes que ello conlleva si el acceso no se hace desde un ordenador (por no extenderme demasiado he obviado el problema de mostrarlo en PCs empequeñeciendo la ventana del navegador).

La primera que voy a analizar es la página de la URJC (Universidad ¿ex? Rey Juan Carlos), donde estudiamos en su dia casi todos los miembros del blog.  Su tráfico aproximado es de 700k de usuarios al mes, hay que decir que no es posible conocer información relativa a los dispositivos desde los que se ha accedido, pero es muy probable que gran parte de ellos dispongan de un smartphone y les resulte mas cómodo que hacerlo desde el ordenador (sobre todo si no se encuentran en casa). Si intentan acceder con un móvil de gama media-alta (pongamos que con pantalla 720p) verían una imagen como la que se muestra mas adelante.

Los emuladores de móviles de Chrome y Firefox muestran la web con ese aspecto, pero según el dispositivo puede mostrarse la web completa, en cualquier caso en un espacio tan pequeño es un engorro ver la información aun usando un móvil de pantalla grande (siendo estudiante, en un país en crisis y con la subida del precio de las matrículas este año lo más normal es que la pantalla que usen sea más bien pequeña).

Veamos otro ejemplo, el CPIICM, cuya página está creada con Drupal (según se puede apreciar en el código) y a priori se espera que sea de calidad, pero como en el caso anterior también es farragoso su uso en el móvil. Teniendo en cuenta que los colegiados pagan una cuota anualmente, da la sensación de un mantenimiento pobre (no tenían por qué complicarse mucho ya que existen un montón temas responsive para Drupal)

Img1 img5

 

Ejemplos de páginas con RWD

Ahora voy a enseñar algunas páginas que si se han molestado en aplicar RWD. Dado que el primer ejemplo que he puesto anterior era de una universidad, en este caso voy a destacar la página de la universidad donde no llegó a graduarse el bueno de Mark Zuckerberg. En este caso el diseño es mas funcional y agradable, a diferencia de los ejemplos anteriores se puede ver toda la información sin tener que pelearse con el zoom y se tiene mejor experiencia de usuario, como resultado el visitante considerará su móvil como una alternativa viable al ordenador, con la ventaja de poder acceder desde cualquier lugar (lo que incrementa las posibilidades de que el número de visitas aumente).

img2

Pero en España también tenemos universidades que cumplen, como la UC3M o la UEM (siendo la primera pública y la segunda privada). Luego están casos como la UCM que lo han dejado a medias (no se comporta bien con algunas resoluciones)

img3

img4

 

 

 

 

 

 

 

 

 

Para los que seáis poco empáticos (o directamente unos psicópatas) voy a ejemplificar gráficamente la reacción de los visitantes de vuestra web que pretendan acceder con su móvil low-cost (aka crisis-friendly). Pongamos que el visitante es Florentino Pérez (puede ser que se le haya roto su iPhone y se haya comprado un móvil barato porque tiene que ahorrar para el nuevo Bernabéu).

Sin RWD

con RWD

 

 

 

 

 

 

Si os interesa el tema, en el próximo post se enseñará una web básica que siga el RWD, siguiendo los puntos explicados para que se entienda mejor, además se usará un plugin jQuery que hará que el resultado final tenga un aspecto similar a una aplicación móvil nativa, pero eso ya otro día.

 

Deja un comentario

Archivado bajo Tutoriales

Crear un servidor web con Node.js (II)

En el anterior capítulo nos quedamos con el servidor Node montado y corriendo. Lo próximo es construir una aplicación más compleja que responda a varias URLs, para ver en movimiento algo de lo que sería REST. Evidentemente, debemos examinar la petición HTTP, extrayendo de ella la URL pedida y, ocasionalmente, sus parámetros GET/POST.

La idea es que para procesar las peticiones necesitamos una especie de router que, dependiendo de la URL, mapee a los distintos manejadores, y en un rato veremos el cómo. En este punto hace falta aclarar un pequeño detalle:

Si comparamos Node con, por ejemplo, un Apache+PHP, hay una diferencia principal: el código PHP contiene la lógica, accesos a base de datos, etc.; es decir, implementa la aplicación, pero es Apache quien se encarga de servirla y gestionar las peticiones. Node realiza las funciones de ambos, no sólo implementamos la aplicación sino también todo el servidor, de forma que la aplicación web y su servidor web son esencialmente lo mismo.

Callbacks y funciones anónimas

Bien, ya vimos la función principal en nuestro hello.js, que crea el servidor y escucha peticiones en el puerto indicado. Al crear el servidor le estamos pasando una función como parámetro, lo cual se puede hacer en JavaScript incluso sin crear anteriormente la función. Es decir, se puede asignar una función a una variable y después pasar esta como parámetro, o bien definir la función en el mismo parámetro y por tanto no hay que darle un nombre (función anónima).

Este tipo de comportamiento se debe a la naturaleza de Node.js y a que trabaja orientado al evento. De esta forma, pasando una función al método que crea el servidor, cada vez que se reciba una petición, esta función será llamada (callback). Así que manipulamos ahí mismo la petición entrante, justo donde se captura el evento.

La estructura de la URL

Por otra parte, a la función que responde al evento (manejador) se le pasan dos objetos, request y response, con cuyas propiedades podemos obtener los detalles de la petición y procesarla adecuadamente.

Repasemos por un momento la estructura de las URLs y las partes que nos pueden interesar. En esencia, una URL puede tener unas cuantas de estas cosas (algunas de ellas están siempre, aunque no las veamos en el navegador, como las meigas):

URL parts

Brevemente:

  • Protocolo: normalmente HTTP, pero también HTTPS, FTP, etc.
  • Host/Hostname: dominio, es decir, nombre o dirección IP de la máquina.
  • Puerto: puerto de red en el que escucha (por defecto 80 en HTTP).
  • Path: ruta en la que se localiza el recurso.
  • Query: parámetros de la petición: pares de variable=valor.

Obviamente, las partes importantes aquí son el path y la query: queremos saber a qué recurso se ha accedido, y si vienen datos con ello. Los obtenemos de la siguiente manera (usando los módulos internos url y querystring):

var url = require(‘url’);
var querystring = require(‘querystring’);

// Obtener el path o la query como cadena
var path = url.parse(request.url).pathname;  // “/hola”
var query = url.parse(request.url).query;  // “nombre=Pepito&apellido=Pérez”
// Obtener el objeto JSON a partir de la cadena query
var params = querystring.parse(query);  // { nombre: Pepito, apellido: Pérez }

A través del objeto request también podemos obtener otras cosas interesantes, como protocolo y versión, método, cabeceras…

Módulos: require y exports

Para dotar a nuestra aplicación de cierta organización, podemos separar todo el código en módulos. Esencialmente, un módulo es un fichero que agrupa ciertas funcionalidades, y que se puede usar posteriormente desde otro fichero.

Vemos en los ejemplos algunas líneas con require. Dado que ‘http’, ‘url’ o ‘querystring’ son módulos (internos de Node.js en este caso), require carga las funcionalidades que dichos módulos proporcionan (exportan).

Ahora nos queda crear nuestros propios módulos, y despues utilizarlos. Dentro de un módulo, podemos elegir qué partes queremos exportar, ya que todo lo que haya dentro es por defecto privado (variables, funciones, clases…). Y de hecho, la palabra que se usa para ello es exports.

Lo explican genial aquí, por lo que me limito a decir que lo haríamos de una de las dos formas:

a)     Exportando los componentes por separado:

var num = 35;
var sumar = function(a, b) {
    return a+b;
}
module.exports.num = num;
module.exports.sumar = sumar;
--------------------------------
var utils = require(‘./modulo);
var x = utils.num + 2;
var res = utils.sumar (4,9);

b)     Exportando todo en una función:

var miClase = function(param1, param2) {
   this.param1 = param1;
   this.param2 = param2;
}
module.exports = miClase;
--------------------------------
var clase = require(‘./miClase’);
var obj = new clase();
// O también:
var obj = new require(‘./miClase’)();

Mezclar y agitar

Muy bien, ya tenemos todos los ingredientes: callbacks y funciones anónimas, partes interesantes de la URL y nuestros propios módulos.

Ya podemos hacernos nuestro router casero, y poder decirle hola y adiós al usuario (un ejemplo muy básico para entender cómo se mapean las peticiones).

Para que no haya confusión, voy a renombrar mi hello.js a app.js (nombre más coherente), y voy a crear también router.js, que será usado en la aplicación principal.

function route(pathname, query) {
    switch (pathname) {
        case "/hola":
            return "Hello " + query["nombre"] + " " + query["apellido"]
        case "/adios":
            return "Bye bye " + query["nombre"] + " " + query["apellido"]
        default:
            return "Este recurso no existe!"
    }
}
exports.route = route;
var http = require('http');
var url = require('url');
var querystring = require('querystring');
var router = require('./router');

http.createServer(function (request, response) {
    res.writeHead(200, {"Content-Type'": "text/html"});

    var pathname = url.parse(req.url).pathname;
    var query = url.parse(req.url).query;
    var params = querystring.parse(query);

    var response = router.route(pathname, params);
    res.write(response);
    res.end();
}).listen(5555);

Claro que se podría hacer algo más elaborado, como tener en cuenta el método (GET/POST) y hacer cosas diferentes con uno y otro, pasarle al router también el objeto response y devolver una página 404 para los recursos que no existan, o bien cambiar el switch y organizar los recursos pedidos de otra manera…

Para todo esto existe una librería que veremos el próximo día: Expressjs 🙂

Saludos!

Deja un comentario

Archivado bajo Tecnologías, Tutoriales

Integración con WS en Scala con Akka-Camel

header-01

Hoy vamos a hablar de la integración con servicios web usando Akka. Si bien implementar dichos servicios puede o no ser un tostón (no soy muy fan de SOAP, la verdad…), la integración, dependiendo de según como estén hechos, puede resultar un tanto complicada (abrir y mantener conexiones, definir protocolos, …). Por eso vamos a plantear el uso de una herramienta con bastante comunidad de trasfondo como es Apache Camel.

Esta herramienta da soporte a la mayoría de EIPs (Enterprise Integration Patterns) que definen en su libro Gregor Hohpe y Bobby Woolf; pudiendo definir rutas estableciendo reglas que manipulan el flujo de datos en el proceso de comunicación. Por poner un ejemplo sencillo, supongamos que queremos consumir mensajes de una cola y escribirlos a fichero. Con Camel podríamos hacerlo usando su DSL de la siguiente forma:

context.addRoutes(new RouteBuilder() {
  public void configure() {
    from("test-jms:queue:test.queue")
      .to("file://test");
  }
});

Como podréis imaginar, estas rutas pueden complicarse todo lo que se quiera. En este caso, con lo que más nos interesa quedarnos de Camel, es con los conceptos de Consumidor y Productor, considerando consumidor aquel extremo del canal que se dedica a obtener mensajes de una cierta fuente, y productor al que se dedica a escribir mensajes (¬¬ … genius!).

Sin entrar muy en detalle de todos los elementos que integran Camel (rutas, endpoints, processors, …), hemos de decir que nos apoyaremos en un componente muy concreto de Camel: camel-cxf, que emplea el framework Apache CXF (nos aporta facilidades a la hora de construir o desarrollar servicios web de tipo SOAP, XML-HTTP, RESTful-HTTP, CORBA… con soporte para distintas capas de transporte como HTTP, JMS o JBI).

Pongamos como ejemplo que queremos crear un cliente para conectarse a un servicio web. Hemos escogido para ello un web-service de carácter público, que no requiere de autenticación, como es WeatherWS, que ofrece información meteorológica del área de Estados Unidos (aquí al lado). Los pasos de la receta son los siguientes:

Generando clases JAXB

Para que la transmisión de datos, que debe ser en XML, no sea la muerte a pellizcos, vamos a utilizar CXF para generar las clases JAXB (Java Architecture for XML Binding). Esta capa de abstracción nos evita trabajar con el XML crudo, pudiendo enviar instancias de estas clases y dejando que el proceso de serialización/deserialización sea transparente al desarrollador.

Para generar estas clases, usamos la herramienta wsdl2java que viene con apache-cxf, el cual podéis descargar de la web.

  1. Descargarmos el fichero WSDL (http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL) que contiene la descripción del servicio y lo renombramos a Weather.wsdl
  2. Ejecutamos la herramienta wsdl2java y decidimos el directorio donde se van a generar (en nuestro caso indicamos el directorio de nuestro proyecto donde van las clases java) :
     wsdl2java -client -p com.cdyne.ws -d src/main/java Weather.wsdl 

Creando el Productor

Dado que Akka dispone de la extensión Camel, podemos ahora crear un actor para enviar peticiones síncronas utilizando la template de productor.

En primer lugar creamos el tipo de mensaje que representa una petición y que va a recibir nuestro actor, ante el cual va a reaccionar.

case class WeatherMessage
  body: java.util.List[String],
  headers: java.util.Map[String, Object])

Y para hacer el código un poco más legible en el cuerpo del actor, creamos un objecto helpers y codificamos en su interior el extractor Response que hará que la respuesta obtenida al hacer la petición sea más fácil de diseccionar para extraer los campos que queremos:

object Response {
  def unapply(obj: Object): Option[List[Any]] =
    try {
      Some(obj.asInstanceOf[MessageContentsList].toArray.toList)
    } catch {
      case _: Throwable => None
    }
}

Posible pregunta suscitada:

Yooo, eehhhh, es que no entiendo el extractor este que te montas. Te has querido molar y…

Tranquilos, ahora se verá mejor en la definición del actor.

En primer lugar creamos la clase:

class MyProducerActor extends Actor

y generamos una instancia de CamelExtension (Atención: ¡Sólo una por instancia de sistema Akka!)

val camel = CamelExtension(context.system)

Luego definimos la URI del endpoint,

val uri = "cxf:http://wsf.cdyne.com/WeatherWS/Weather.asmx?" +
  "serviceClass=com.cdyne.ws.WeatherSoap"

y por último definimos el comportamiento del actor (atentos al extractor de antes :P):

def receive = {

  case WeatherMessage(body, headers) =>
    camel.template.requestBodyAndHeaders(uri, body, headers) match {

      case Response(List(awd: ArrayOfWeatherDescription)) =>
        awd.getWeatherDescription().toList map format foreach println

      case Response(List(wr: WeatherReturn)) =>
        println(format(wr))

      case Response(List(fr: ForecastReturn)) =>
        println(format(fr))

      case response => println(response)

    }

}

Luego si queremos probar nuestro cliente, bastará con crearnos un productor y enviarle un WeatherMessage con los parámetros adecuados:

val myProducer = system.actorOf(Props[MyProducerActor])
val operation = "GetWeatherInformation"
val params: java.util.List[String] = List()
val request = WeatherMessage(params, Map(
  "operationName" -> operation,
  "soapAction" -> s"http://ws.cdyne.com/WeatherWS/$operation"))

myProducer ! request

Conclusión

De esta manera, es sencillo integrar nuestro sistema de actores Akka con servicios web. Si juntamos la potencia de Scala, con la escalabilidad de Akka y nos apoyamos en herramientas de gran versatilidad como son Camel o CXF podemos generar clientes WS de una alta calidad y sin traumarnos (Dejad que los SOAP se acerquen a mí…).

Tenéis disponible el código que se ha utilizado como ejemplo en Github.

Y como diría Salvador Raya:

«Cenquiu veri mach. Suscribi plis»

Deja un comentario

Archivado bajo Tutoriales

Crear un servidor web con Node.js (I)

Ya vimos aquí en que consistía la arquitectura REST; ahora es el turno de poner en práctica ese esquema implementando nuestro propio servidor web, y el lenguaje afortunado va a ser Javascript.

¿Cómor? ¿Javascript en el servidor?

¡Si yo creía que se utilizaba en el cliente para hacer mi web más interactiva! Modificar sobre la marcha la estructura del documento, alterar su apariencia, gestionar eventos…

Pues sí, pero además se puede construir con él un servidor aprovechando todas sus ventajas. Claro que la manera de desarrollar con Javascript en el servidor es diferente a cómo lo usamos en el navegador.

En este sentido, Javascript es un lenguaje de programación “completo” como cualquier otro, y podemos hacer con él las mismas cosas que con los demás. Si quieres conocerlo y exprimirlo, te recomiendo que eches un vistazo a los muchos manuales y libros que pululan por Internet, como este.

Javascript es un lenguaje idóneo para programación orientada a eventos: permite funciones anónimas, la sintaxis es similar a muchos otros lenguajes, y los callbacks que se llaman al dispararse los eventos se pueden escribir en el mismo punto en el que se captura el evento. Sencillo de implementar y de mantener. Esperar un evento, devolver la llamada, et voilà.

Node.js

El problema con muchos lenguajes de servidor (como PHP), es que cada conexión genera un nuevo hilo, con el consiguiente consumo de recursos: procesador, memoria… Por lo tanto, un sistema con una cantidad limitada de RAM tiene un máximo teórico de conexiones concurrentes. Si la base de datos de clientes crece mucho, habrá que añadir más y más servidores, lo que supone más y más costes: los propios servidores, lógica de negocio, costes laborales, problemas técnicos potenciales, etc.

Conclusión: número limitado de conexiones concurrentes = gran cuello de botella.

Aquí es donde surge Node.js, que resuelve este problema cambiando la forma en la que se realizan estas conexiones. Por cada nueva conexión, en lugar de generarse un nuevo hilo de SO, se dispara un evento en el motor de ejecución.

Node es un intérprete Javascript que corre en el lado del servidor, es decir, fuera del navegador. Permite construir fácilmente aplicaciones de red muy rápidas y altamente escalables, y manejar miles de conexiones simultáneas en la misma máquina física.

Para ello, utiliza un modelo dirigido por eventos con E/S no bloqueante, lo que lo hace ligero y eficiente, perfecto para aplicaciones de uso intensivo de datos en tiempo real.

Lo que hace Node es interpretar y ejecutar el código Javascript, haciendo uso de la máquina virtual V8 de Google, el mismo entorno de ejecución para Javascript que utiliza Google Chrome.

Además, cuenta con una gran colección de módulos con diferentes utilidades, de modo que se simplifican muchas tareas.

Por lo tanto, Node es dos cosas: un entorno de ejecución y una librería.

Los módulos sirven para expandir la funcionalidad de Node. Son tan importantes que se han convertido en una parte esencial del producto completo. Aquí entra en juego npm (Node Package Manager), el gestor de paquetes, que es una forma integrada de instalar y administrar los módulos y sus dependencias. Un extra es que uno mismo puede publicar sus propios módulos y contribuir así a la comunidad de desarrolladores.

Según todo esto que hemos visto, Node está diseñado para situaciones en las que esperamos una gran cantidad de tráfico y donde la lógica y procesamiento requeridos no sean necesariamente grandes.

Instalación y actualización

En primer lugar, debemos instalar Node.js siguiendo estas instrucciones. Allí se explican los prerrequisitos, problemas comunes y la forma de compilarlo (build) en los distintos sistemas operativos; aunque la manera más sencilla es instalarlo directamente sin compilarlo (como yo voy a hacer), bien de forma automática o bien manual.

Yo estoy utilizando Windows, por lo que las instrucciones siguientes son para instalarlo en este SO, pero si estáis en Linux/UNIX o Mac podéis hacer el build como se explica en dicha web, o instalarlo siguiendo las instrucciones del final de la misma, es decir, mediante el gestor de paquetes de cada SO o descargando los binarios correspondientes para cada plataforma.

Se recomienda realizar la instalación manual para atajar los problemas de hacerlo automáticamente. Los pasos a seguir son sencillísimos:

  • Crear un directorio vacío y añadirlo a la variable PATH del sistema.
  • Descargar la última versión del .exe de Node.js correspondiente (32 o 64 bits) en ese directorio.
  • Descargar la última versión del .zip de npm (el gestor de paquetes de Node) y descomprimirlo en el mismo directorio.

Si, de todas formas, queremos hacerlo de forma automática, basta con descargar la última versión del paquete .msi (instalador para Windows), y con él se instalará tanto Node.js como npm.

De esta forma y gracias al PATH ya podremos ejecutar scripts (node scriptname.js) e instalar módulos (npm install modulename) en cualquier directorio (no olvidéis abrir un terminal y probar ambos comandos ;)).

Para actualizar el propio Node o npm, basta con hacer lo siguiente:

  • Descargar la última versión del .exe de Node.js correspondiente (32 o 64 bits), igual que el segundo paso anterior, y reemplazar el viejo .exe con él.
  • Para npm, ejecutar el comando: npm update npm –g

¡Hello World!

¡Por fin! Ya tenemos todo instalado y configurado, y vamos a probarlo escribiendo el clásico saludo de bienvenida en cualquier lenguaje.

Abrid vuestro editor favorito (desde Bonus4Code os recomendamos Sublime) y cread un archivo de extensión .js. El mío va a ser hello.js.

Dentro podríamos escribir un simple comando que escribiese ‘Hola’ por pantalla (en stdout) al ser ejecutado, pero como hablamos de webs, vamos a crear el servidor y que nos lo devuelva mejor en el navegador, ¿no? 🙂

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {“Content-Type': 'text/html”});
    res.write(“Hello World”);
    res.end();
}).listen(5555);

console.log('Servidor haciendo algo en: http://127.0.0.1:5555/');

Guardamos, abrimos un terminal y ya sabemos:

node hello.js

Debería mostrarse el mensaje de log, y el servidor ya está corriendo. Así que sólo queda ir al navegador, entrar en http://localhost:5555 y ver nuestro Hello World en acción (eso sí, muy feíto el pobre y sin ningún estilo…).

Más en próximas entregas 😀

Deja un comentario

Archivado bajo Tecnologías, Tutoriales

Servicios Web RESTful

REST es el acrónimo de REpresentational State Transfer, o Transferencia de Estado REpresentacional. Describe un estilo arquitectural para diseñar aplicaciones en red, y se presentó por primera vez en el año 2000. La idea es utilizar simplemente HTTP para realizar llamadas entre máquinas, en lugar de otros mecanismos o protocolos más complejos.

rest-2

Pero, ¿en qué consiste? ¿Por qué se llama así?

El concepto más importante en REST es la existencia de recursos (elementos de información de los que se compone la Web), que pueden ser accedidos utilizando un identificador (URI). Para manipular estos recursos, los clientes y servidores de la red se comunican a través de una interfaz estándar (HTTP en este caso) e intercambian representaciones de estos.

Cuando se realizan peticiones a través de las URLs, se devuelve una representación de esos recursos, la cual deja la aplicación en un estado. Otras acciones (pedir otra URL, navegar a través de un enlace), hacen que se devuelva otro recurso, y esta nueva representación cambia de estado nuevamente la aplicación. De esta forma, con cada representación de los recursos, la aplicación cambia (transfiere) de estado.

Por lo tanto, REST define un conjunto de principios arquitectónicos para diseñar servicios web en los que los protagonistas son los recursos, incluyendo cómo se accede a su estado y cómo se transfieren a los clientes.

¿Estándar?

Ojo, REST no es un estándar con una especificación definida por el W3C. Tampoco se encarga de los detalles de implementación del servidor (es indiferente que el servicio web esté construido con PHP, servlets de Java, CGI… un servicio REST es independiente del lenguaje y de la plataforma). Es sólo un estilo que se puede seguir para diseñar un servicio web. Sin embargo, sí se basa en estándares:

  • HTTP
  • URL
  • XML/HTML/GIF/JPEG/etc (representaciones de los recursos)
  • text/xml, text/html, image/gif, image/jpeg, etc (Tipos MIME)

REST por sí solo tampoco ofrece características de seguridad, encriptación, gestión de sesiones… Por supuesto, y como en cualquier servicio web, estas funciones se pueden añadir por encima de HTTP: mediante usuarios y contraseñas, SSL, cookies…

REST ha ido teniendo una amplia acogida en toda la web y en la comunidad de desarrolladores, ya que es un modelo más fácil de usar, orientado a los recursos.

Los sistemas que siguen este esquema se denominan RESTful.

rest-1

¿Y cuáles son esos principios?

Como decíamos, REST describe los fundamentos que hacen posible que la Web funcione bien y sea altamente escalable. Estos diseños fundamentales son:

  • No se mantiene el estado: cada petición HTTP contiene toda la información necesaria para ser comprendida. Como resultado, ni el cliente ni el servidor necesitan recordar ningún estado de las comunicaciones entre mensajes. De esta forma, se mejora el rendimiento de los servicios y se hace más simple su diseño e implementación. En la práctica, sabemos que HTTP no mantiene estado, por ello muchas aplicaciones utilizan cookies y otros mecanismos para mantener la sesión (algunas de estas prácticas no son permitidas por REST).
  • Un conjunto de operaciones bien definidas que se aplican a los recursos de forma inequívoca. En el caso de HTTP existen unas operaciones, que deben usarse de forma consecuente con la definición del protocolo:
  • GET: para obtener un recurso. Debe ser idempotente.
  • POST: para crear un recurso.
  • PUT: para modificar un recurso o cambiar su estado.
  • DELETE: para eliminar un recurso.
  • Una sintaxis universal para identificar los recursos. En un sistema REST, cada recurso es direccionable únicamente a través de su URI. Estas URIs se definen de forma análoga a una estructura basada en directorios, de forma que la jerarquía es fácilmente comprensible y necesita escasa documentación.
  • El formato de datos que el servicio utiliza en las peticiones y respuestas: la representación del estado de un recurso en un sistema REST es típicamente HTML o XML (a veces JSON), donde la estructura devuelta podría corresponderse con un registro de la base de datos, y el contenido de las etiquetas mostrase los valores de las filas. Esto permite que el servicio sea utilizado en diferentes plataformas, lenguajes y dispositivos.

URLs lógicas y URLs físicas

Un recurso es una entidad, un concepto. Una representación de este recurso es una manifestación concreta de éste. Cuando accedemos, por ejemplo, a la URL

http://www.misitio.com/persona/5897

se trata de una URL lógica, no física. Obviamente, no existe una página HTML estática para cada una de las personas en ese site, ni una carpeta anidada por cada nivel en la URL. De ser así, el diseño no sería muy escalable precisamente.

Simplemente, la URL contiene toda la información necesaria para acceder al recurso; el primer paso natural es el de ‘parsear’ la petición, mientras que los detalles de implementación del servidor quedan ocultos: puede tratarse, por ejemplo, de una consulta de base de datos en una tabla ‘personas’ cuyo id sea el 5897, etc.

La cuestión es que las URLs no revelan ningún tipo de información sobre los ficheros existentes, ni tampoco sobre la implementación. Ésta se debe poder cambiar sin que ello afecte a la estructura de las URLs en la página.

En próximos episodios veremos cómo podemos construir desde cero, y de una manera muy sencilla nuestro servidor web con una API REST utilizando… bueno, no os lo cuento. ¿Dejamos la incógnita unos días?

1 comentario

Archivado bajo Tecnologías