<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Yo en el Universo &#187; rest</title>
	<atom:link href="http://sixservix.com/blog/david/tag/rest/feed/" rel="self" type="application/rss+xml" />
	<link>http://sixservix.com/blog/david</link>
	<description>El blog de David Bonilla</description>
	<lastBuildDate>Fri, 24 Jun 2011 05:30:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>HTTP Access Control: programando REST de VERDAD</title>
		<link>http://sixservix.com/blog/david/2011/02/16/http-access-control-rest/</link>
		<comments>http://sixservix.com/blog/david/2011/02/16/http-access-control-rest/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 05:15:01 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[desarrollo]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[cross-site scripting]]></category>
		<category><![CDATA[HTTP Access Control]]></category>
		<category><![CDATA[Jersey]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[Restlet]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=5210</guid>
		<description><![CDATA[La mayoría de los que hablan de REST son un fraude que no han hecho NADA REAL con dicha tecnología. Averigua que pasa cuando te pones con las manos en la masa.


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/' rel='bookmark' title='Permanent Link: Explicando REST a mi madre'>Explicando REST a mi madre</a> <small>Si mamá, desde hace ya un buen tiempo, cuando vienes...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-5212" style="border: 0pt none;margin-right: 10px" title="httpaccesscontrol" src="http://sixservix.com/blog/david/files/2011/01/httpaccesscontrol.jpg" alt="HTTP Access Control" width="302" height="225" />Un FRAUDE. La mayoría de <a title="Explicando REST a mi madre" href="http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/" target="_blank">la gente que habla de <strong>REST</strong></a> y de la revolución que va a suponer en el diseño y consumo de aplicaciones en Internet son un fraude, gente que no ha hecho NADA REAL que se aleje cinco pasos más allá de la teoría.</p>
<p style="text-align: justify">Pero, a veces, el destino es caprichoso y te lleva por caminos insospechados. Te encargan que hagas un prototipo en Android y, cuando te quieres dar cuenta, estás <em>RESTificando </em>tu<em> </em>aplicación para conectarte a ella, <em>como Dios manda</em>, desde tu zapatófono con el sistema operativo de Google.</p>
<p style="text-align: justify">Y, cuando te pones en serio a implementar algo, pasa lo de siempre: que te manchas las manos y nada es tan limpio como parece. Perdí al menos un par de horas intentando descubrir por qué el <strong>REST </strong>del demonio no funcionaba como se supone que debía hacerlo.</p>
<p style="text-align: justify">Así que decidí escribir un <strong>artículo técnico</strong>. De esos que dan <em>prestigio </em>y hacen que no te etiqueten exclusivamente como un <em>businessman</em>. Sí, de <a title="EJB 3.1" href="http://sixservix.com/blog/david/2010/05/10/transacciones-bloqueos-glassfish-v3-ejb31-jpa2/" target="_blank">esos artículos que no lee ni mi mujer</a>. Eso sí, ya que no lo iba a leer nadie, lo he escrito a mi manera, nada de <em>ladrillos incendiarios</em> como <a href="http://www.javahispano.org/contenidos/es/el_placer_de_la_programacion_asincrona/" target="_blank">los que se gasta el maligno y vehemente Dr. Arranz</a>.</p>
<p style="text-align: justify">Si quieres saber qué es eso del <strong>HTTP Access Control</strong> y por qué debes tenerlo en cuenta cuando desarrolles en <strong>REST</strong>, sigue leyendo.</p>
<p style="text-align: justify">Banda Sonora del artículo: <a title="In One Ear - Cage The Elephant" href="http://open.spotify.com/track/5dJJnW69ejYOfuntLuLJft" target="_blank">Cage the Elephant &#8211; In One Ear</a></p>
<h3 style="text-align: justify">EL CONTEXTO</h3>
<p style="text-align: justify">Con una aplicación <em>legacy </em>-y una aplicación en <strong>Struts 1</strong> lo es-, lo más lógico es recurrir a un <em>framework </em>que te ayude a implementar REST sin tener que entrar como un elefante en una cacharrería ni reinventar la rueda. Según Google, tenía dos opciones básicas: <a title="Jersey" href="http://jersey.java.net/" target="_blank">Jersey</a>, la implementación de referencia de Oracle/SUN y <strong><a title="Restlet" href="http://www.restlet.org/about/" target="_blank">Restlet</a></strong>, el voluntarioso esfuerzo que da de comer a <strong>Noelios Technologies</strong>.</p>
<div id="attachment_5250" class="wp-caption alignright" style="width: 362px"><a href="http://sixservix.com/blog/david/files/2011/01/introductionAPIRestlet.jpg"><img class="size-full wp-image-5250" style="border: 0pt none;margin-left: 10px" title="introductionAPIRestlet" src="http://sixservix.com/blog/david/files/2011/01/introductionAPIRestlet.jpg" alt="" width="352" height="310" /></a><p class="wp-caption-text">La introducción de la API 2.4.1 de RESTLET es muy LOL :D</p></div>
<p style="text-align: justify"><strong>Jersey </strong>debe ser una maravilla, pero ha debido de ser el último <em>framework </em>en sufrir el <a href="http://eddieamos.wordpress.com/2010/07/30/oracle-suffers-a-homer-simpson-moment-when-rebranding-java-from-sun-to-oracle-duh/" target="_blank"><em>rebranding</em> de Oracle</a> y no me funcionaba ni un solo enlace a la documentación. Así que la elección estaba clara.</p>
<p style="text-align: justify">Lo malo de <strong>Restlet </strong>es que, el cambio de la versión 1 a la 2 ha sido más traumático que encontrarte a tu abuela desnuda en la ducha, así que todos los <a href="http://danilogurovich.wordpress.com/2008/09/23/a-simple-restlet-demo-application/" target="_blank">ejemplos</a> que encontraba sobre cómo utilizar <strong>Restlet </strong>valían lo mismo que un billete de 7 euros.</p>
<p style="text-align: justify">Algunos cambios eran sencillitos, como el <em>rename </em>de <em>Resource </em>a <em>ServerResource</em>, pero otros -el constructor de <em>ServerResource </em>ya no recibe como parámetros un <em>Request </em>y un <em>Response </em>sino que la factoría de creación los inyecta después de instanciar el objeto- te obligaban a hacer lo que hacen los hombres de verdad: remangarse la camisa y tirar de API.</p>
<p style="text-align: justify">Implementé <a href="http://danilogurovich.wordpress.com/2008/09/23/a-simple-restlet-demo-application/" target="_blank">el mejor ejemplo que encontré</a>, adaptándolo para que funcionara con <strong>Restlet 2,</strong> incrustado en mi aplicación <em>legacy</em>, y creé un HTML+JavaScript (del bueno) independiente, con un formulario básico que me permitiera indicar la URL, parámetros y método HTTP que quisiera probar. Un figura, ese soy yo.</p>
<h3 style="text-align: justify">EL MURO DE CEMENTO</h3>
<p style="text-align: justify">Empiezo a probar mi implementación a través de mi cliente  y la cosa parece que funciona: consigo controlar el flujo de la aplicación -hasta un <em>catch-all</em>-, recoger parámetros y devolver mi <em>Response</em>&#8230; pero, cuando llega a mi cliente, un flamante <strong>Firefox</strong> <strong>3.6.2</strong>,  el <a title="HTTP Status" href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes" target="_blank">HTTP Status</a>, ese que te indica que todo ha ido como la seda o que has metido la pata, es un cero patatero. <strong>¿¿¿ Cero ??? WTF ???</strong></p>
<p style="text-align: justify">Bueno&#8230; el <strong>HTTP Status</strong> es básico para validar las cosas van bien, pero podría llegar a prescindir de él. Ya validaré los datos del <em>Response</em>, a lo Pancho Villa, en cliente, pero es que&#8230; ¡tampoco llegan los datos! Ostras, esto ya es más grave.</p>
<p style="text-align: justify">Se me enciende la bombilla y pienso &#8220;claro, eso es porque no indicas el <em>status</em> antes de devolver la <em>Response </em>desde tu aplicación de servidor&#8221; y me pongo a hacer idioteces como esta en <strong>Restlet</strong>:</p>
<pre style="text-align: justify">setStatus(Status.SUCCESS_OK);</pre>
<p style="text-align: justify">
<p style="text-align: justify">¡Pero tampoco funciona! ¡Maldita sea! Y, lo peor de todo, es que, cuando llamaba a los servicios directamente por invocación desde la barra del navegador en vez desde mi HTML+JavaScript (del bueno) independiente, todo funcionaba bien&#8230; ¬¬</p>
<h3 style="text-align: justify">EL PROBLEMA</h3>
<p style="text-align: justify">Después de comprobar unas 20 veces que tenía todo BIEN y, aún así, todo funcionaba MAL, me dio por <em>googlear </em>&#8216;HTTP Status ==  0&#8242; y<strong> la explicación que encontré era tan simple que no podía creerlo</strong>. Lo más increíble de todo era el párrafo que decía &#8220;.<em>.. y no te funcionará en otro navegador que no sea Explorer</em>&#8220;. Así que,  me esforcé por recordar cómo podía abrir el Internet Explorer, ejecuté mi cliente HTML+JavaScript (del bueno) con él y&#8230; <em>voilà</em>! El navegador no solo recibía un <em>Status </em>200 <em>aka </em>&#8220;todo ha ido fino Pochettino&#8221; sino que me pintaba, con mi AJAX de todo a 100, los datos de respuesta del servidor.</p>
<p style="text-align: justify">Al final, todo era una cuestión de seguridad&#8230; y de <strong><em>cross-site scripting</em></strong>.</p>
<p style="text-align: justify">Si os leéis este <a href="https://developer.mozilla.org/En/HTTP_Access_Control" target="_blank">textazo técnico de Mozilla</a>, aprenderéis que, por defecto, Firefox implementa una restricción de seguridad que impide el <em>cross-site request</em> o, lo que es lo mismo, <strong>que un recurso de un dominio A haga una petición de un recurso del dominio B</strong>.</p>
<p style="text-align: justify">En mi caso, mi cliente HTML estaba alojado en mi disco duro, mientras que el recurso que solicitaba por REST era servido por  un TOMCAT en local &#8230; pero  evidentemente en dominio diferente para el navegador.</p>
<p style="text-align: justify">La solución consiste en incluir una cabecera especifica en la <em>HTTP Response</em> que se envía de vuelta al navegador: <strong>Access-Control-Allow-Origin</strong></p>
<p style="text-align: justify">Mediante esta cabecera, desde el servidor podemos avisar al navegador de qué dominios están autorizados para solicitar recursos de nuestro sitio. <strong>Si queremos permitir el acceso a nuestra API REST desde cualquier dominio</strong>, como en mi caso, tendremos que darle el valor &#8220;*&#8221; a dicha cabecera.</p>
<h3 style="text-align: justify">LA SOLUCIÓN</h3>
<div id="attachment_5372" class="wp-caption alignright" style="width: 279px"><a href="https://gist.github.com/816701"><img class="size-medium wp-image-5372  " style="border: 0pt none;margin-left: 10px" title="gist" src="http://sixservix.com/blog/david/files/2011/02/gist-269x300.jpg" alt="Cacho código" width="269" height="300" /></a><p class="wp-caption-text">Soy un looser y no sé cómo incrustar un snippet de GitHub en el WordPress. No me funciona ni un plugin !!! O_o</p></div>
<p style="text-align: justify">El problema es que con <strong>Restlet </strong>no manejamos directamente las cabeceras HTTP, sino que estas se manejan encapsuladas en <em>wrappers</em> propios de la aplicación.</p>
<p style="text-align: justify">Para poder escribir esta cabecera, debemos recuperar este <em>wrapper </em>en forma de objeto <a title="org.restlet.data.Form" href="http://www.restlet.org/documentation/2.0/jse/api/org/restlet/data/Form.html" target="_blank">Form</a> y añadir la cabecera directamente.</p>
<p style="text-align: justify">Para evitar hacer esto en cada método (GET, POST, PUT&#8230;) de nuestro <a title="org.restlet.resource.ServerResource" href="http://www.restlet.org/documentation/2.0/jse/api/org/restlet/resource/ServerResource.html" target="_blank">ServerResource</a>, he sobrescrito el método <strong><em>do Init</em>()</strong> que se ejecuta cada vez que se instancia el objeto.</p>
<p style="text-align: justify">Es evidente que podríamos hacer una refactorización inmediata y hacer que nuestros <strong>ServerResources </strong>(realmente, los recursos REST que exponemos gracias a <strong>Restlet</strong>) no extiendan directamente de esa clase abstracta sino de una implementación propia que sobrescriba el <strong><em>doInit</em>()</strong> para todos.</p>
<p style="text-align: justify">Como soy un auténtico perdedor, no he conseguido copiar el fragmento de código que había colgado en <strong>GitHub</strong>, pero aquí os dejo <a title="Más que código, oro puro" href="https://gist.github.com/816701" target="_blank">el enlace</a>.</p>
<p style="text-align: justify">Queda mucho por hablar de cómo juguetear, de verdad, con REST (autenticación, el <strong><em>preflighted </em></strong>o verificación previa, etc), pero por hoy es suficiente. Ya os habéis tragado un articulazo de casi 1200 palabras.</p>
<p style="text-align: justify"><span style="color: #008000"><strong>DISCLAIMER: La verdad es que no hace falta nada de esto para trabajar con mi aplicación de Android. En Android, pondría un cliente de </strong><strong>Restlet y se comunicaría con mi aplicación por conexión directa, nada de navegador.</strong></span></p>
<p style="text-align: justify"><span style="color: #008000"><strong>También es importante que sepáis que mucha gente no utiliza el</strong></span> <span style="color: #339966"><span style="color: #008000"><strong><strong><em>Access-Control-Allow-Origin</em> </strong>con valor *, sino que gestionan una lista blanca de dominios autorizados. ¿A alguien le suena el registro de dominio para utilizar las APIs de Google?</strong></span><br />
</span></p>
<p style="text-align: justify">
<p style="text-align: justify">
<p style="text-align: justify">
<p style="text-align: justify">


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/' rel='bookmark' title='Permanent Link: Explicando REST a mi madre'>Explicando REST a mi madre</a> <small>Si mamá, desde hace ya un buen tiempo, cuando vienes...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2011/02/16/http-access-control-rest/feed/</wfw:commentRss>
		<slash:comments>96</slash:comments>
		</item>
		<item>
		<title>Trabajando con Twitter y Java</title>
		<link>http://sixservix.com/blog/david/2009/12/15/twitter-y-java/</link>
		<comments>http://sixservix.com/blog/david/2009/12/15/twitter-y-java/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 06:45:22 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[tuenti]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[twitter4j]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=1308</guid>
		<description><![CDATA[Si no tienes ni idea de lo que es Twitter estás out, fuera, finito, acabado&#8230; y te estás perdiendo el big kahuna del momento en Internet. Te recomiendo que te pongas las pilas y que lo hagas YA. Si eres un desarrollador y piensas &#8220;A mí plin Paquirrín. Eso no tiene nada que ver conmigo&#8220;, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-full wp-image-1310" style="margin-left: 8px;margin-right: 8px" src="http://sixservix.com/blog/david/files/2009/12/twitter-social-icons.jpg" alt="twitter-social-icons" width="192" height="190" />Si no tienes ni idea de lo que es <strong>Twitter</strong> estás <em>out</em>, fuera, <em>finito</em>, acabado&#8230; y te estás perdiendo el <em>big kahuna</em> del momento en Internet. Te recomiendo que te pongas las pilas y que lo hagas YA.</p>
<p style="text-align: justify">Si eres un desarrollador y piensas &#8220;<em>A mí plin Paquirrín. Eso no tiene nada que ver conmigo</em>&#8220;, disculpa si te lo digo con crudeza: <span style="text-decoration: underline">eres un <em>looser</em></span>. Saca durante un instante la cabeza de <strong>Hibernate </strong>y <strong>Spring </strong>porque te están impidiendo ver el sol :).</p>
<p style="text-align: justify"><strong>Twitter </strong>no es sólo una <em>página güel</em>, no es sólo un &#8220;<em>Facebook pero en pequeño</em>&#8221; ni la última tontuna de los modernos de turno. <strong>Twitter es una plataforma</strong> y, como tal, debes aprender a desarrollar para ella. Porque nunca sabes cuándo te puede venir bien utilizarla y porque, créeme, a tus clientes les puede parecer más o menos interesante que utilices Toplink, Hibernate o SQL con escoplo y martillo, pero es probable que alguno te pida algo para <strong>Twitter</strong>. ¿Quieres quedar como un zocolotroco desfasado o como un <em>gurú del Interné</em>? Invertir <strong>5 minutos</strong> en la lectura de este articulo separa una cosa de la otra.<span id="more-1308"></span></p>
<h3 style="text-align: justify">¿UNA PLATAFORMA?</h3>
<p style="text-align: justify">Si amigo, <strong>Twitter  es una plataforma</strong>. Y ¿por qué es una plataforma? Porque <span style="text-decoration: underline">te proporciona una completa <strong>API REST </strong>para que utilices todos los servicios que ofrece desde tu propia aplicación</span> de una forma sencilla y gratuita.</p>
<p style="text-align: justify">Ésta es la clave del éxito de páginas como Twitter o Facebook, su espíritu de <strong>auténticas plataformas donde terceros desarrollen sus propias aplicaciones</strong>.</p>
<div id="attachment_1328" class="wp-caption alignright" style="width: 218px"><a href="http://sixservix.com/blog/david/files/2009/12/plataforma.jpg"><img class="size-full wp-image-1328" src="http://sixservix.com/blog/david/files/2009/12/plataforma.jpg" alt="plataforma" width="208" height="208" /></a><p class="wp-caption-text">Sí, twitter es una plataforma, pero NO de este tipo...</p></div>
<p style="text-align: justify">Sí, Facebook está muy bien, pero ¿alguien puede imaginárselo sin los cientos de juegos del tipo &#8220;¿Quien es el más listo de tus amigos?&#8221; o &#8220;El Granjero que llevas dentro&#8221;? ¿Y sin las miles de aplicaciones para enviar osos amorosos o bocatas de calamares a tus amigos? <span style="text-decoration: underline">La genialidad de Twitter y Facebook es conseguir que terceros desarro</span><span style="text-decoration: underline">l</span><span style="text-decoration: underline">len, sin coste alguno para ellos, y hagan crecer y enriquezcan la plataforma</span>. ¿Que esos terceros también se lucran? &#8220;Genial&#8221;, piensan ellos, así ganamos todos.</p>
<p style="text-align: justify">Por poneros un ejemplo de lo que NO es una plataforma, tenemos a nuestro propio clon local y <em>reggaetonero </em>de Facebook: <em>el Tuenti</em>. No hay un enlace a &#8220;Desarrolladores&#8221; o a &#8220;API&#8221; en la web de Tuenti. Ellos se lo guisan y ellos se lo comen. Vale, veremos como les va, pero, de momento, <a href="http://trends.google.com/websites?q=tuenti.com%2C+facebook.com&amp;geo=ES&amp;date=all&amp;sort=1" target="_blank">van cuesta abajo y sin frenos</a>.</p>
<h3 style="text-align: justify">VALE ¿CÓMO EMPEZAMOS?</h3>
<p style="text-align: justify">Lo primero que tienes que hacer es dar de alta una cuenta en <strong>Twitter</strong>.<strong> </strong>¿Por qué? Porque con esa cuenta podrás registrar tus aplicaciones. Necesitamos registrar las aplicaciones en Twitter para utilizar <a href="http://oauth.net/" target="_blank">OAuth</a> como medio de autenticación.</p>
<p style="text-align: justify">La verdad, podríamos pasar del <strong>OAuth</strong> para hacer nuestra primera aplicación, pero ya que nos ponemos a juguetear con Twitter, mejor aún si aprendemos algo nuevo y ¡Carambolas! <strong>¡El OAUth mola!</strong> :)</p>
<p style="text-align: justify">
<div id="attachment_1336" class="wp-caption alignleft" style="width: 236px"><img class="size-full wp-image-1336 " src="http://sixservix.com/blog/david/files/2009/12/oauth.jpg" alt="Key y Secret de Oauth que se obtiene al registrar la aplicación" width="226" height="262" /><p class="wp-caption-text">Key y Secret de Oauth que se obtiene al registrar la aplicación</p></div>
<p style="text-align: justify">Hablar de <strong>OAuth </strong>no es el objetivo de este post, pero lo describiré de un modo breve. Básicamente, el método de autenticación OAuth se basa en que, <strong>el usuario no se autentica en tu web mediante usuario y contraseña</strong> sino que lo hace en la plataforma que gestione la autenticación (por ejemplo, Twitter) y ésta te da un <em>token</em> de autenticación que es el que tu guardas y utilizas para comunicarte en el futuro con dicha plataforma.</p>
<p style="text-align: justify">Evidentemente, ese <em>token </em>vale para y SÓLO para tu aplicación. Ahí está el truco. Y, para que la plataforma sepa qué aplicación es la que está requiriendo autenticación, te proporciona unas claves que tú envías cuando haces las llamadas de validación de claves. Twitter, al <a href="http://twitter.com/oauth_clients/new" target="_blank">registrar una aplicación</a>, te da las claves necesarias para  trabajar con <strong>OAuth</strong> desde tu aplicación.</p>
<p style="text-align: justify">
<p style="text-align: justify">
<p style="text-align: justify">Ah, una última cosa: como desarrolladores, Twitter nos asigna una serie de cuotas para el uso de sus servicios (recordemos, gratuitos). En concreto, <strong>150 llamadas a la API por hora y por IP/Cuenta de Usuario</strong>.</p>
<p style="text-align: justify">Si nos hemos emocionado con todo esto de las plataformas y tenemos pensado desarrollar <em>La Madre de todas las Aplicaciones de Twitter</em>, podemos solicitar en <a href="http://twitter.com/help/request_whitelisting" target="_blank">este enlace</a> que nos amplíen la cuota <strong>hasta 10.000 llamadas a la hora</strong>, pero, de momento, no creo que sea necesario.</p>
<p style="text-align: justify">Ahora sí, tenemos todo lo que hay que tener para empezar a desarrollar nuestra primera aplicación para <strong>Twitter</strong>.</p>
<h3 style="text-align: justify">MANOS A LA OBRA</h3>
<p style="text-align: justify">Como hemos comentado antes, <span style="text-decoration: underline">la API para trabajar con <strong>Twitter</strong> es una <strong>API REST</strong></span>. Si no sabes lo que es REST, aquí tienes un <a href="http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/" target="_blank">excelente artículo</a> :P sobre el tema, pero, en cualquier caso, no te preocupes. <span style="text-decoration: underline">No te hace falta saber absolutamente nada de REST</span> porque utilizaremos uno de los <strong>envoltorios Java</strong> que ya están creados. Si eres capaz de invocar un <em>System.out.println()</em>, serás capaz de trabajar con esta API.</p>
<p style="text-align: justify">En la propia <a href="http://apiwiki.twitter.com/Libraries" target="_blank">página de librerías Twitter</a> tienes un montón de <em>frameworks </em>ordenados por lenguaje. Voy a centrarme en las opciones que hay para Java, el lenguaje que utilizo y amo, y dentro de éstas, en <a href="http://yusuke.homeip.net/twitter4j/en/index.html" target="_blank">Twitter4j</a>. Más que nada, porque es la que mejor diseño y documentación tiene.</p>
<p style="text-align: justify">Vamos a ir describiendo, paso por paso, <strong>cómo crear nuestra aplicación java/twitter</strong>:</p>
<ol>
<li>Descargamos la librería de la web de Twitter4j. En un fichero <em>zip</em>, encontraremos tanto la librería en sí como el resto de librerías que necesita para funcionar y, si lo preferimos, un fichero <em>pom </em>de <strong>Maven </strong>con todas las dependencias.</li>
<li>Instalamos el conjunto de librerías, tanto Twitter4j como aquellas de las que depende, haciéndolas accesibles a nuestro <em>classpath</em></li>
<li>Nos crearemos la clase<em> BoniTwitterTest</em> donde copiaremos el siguiente código:</li>
<p style="text-align: justify">
<p>[java autolinks="false" classname="BoniTwitterTest" collapse="true" firstline="1" gutter="true" htmlscript="false" light="false" padlinenumbers="false" smarttabs="true" tabsize="4" toolbar="true"]</p>
<p>import twitter4j.Twitter;<br />
import twitter4j.TwitterException;<br />
import twitter4j.Status;<br />
import twitter4j.http.RequestToken;<br />
import twitter4j.http.AccessToken;</p>
<p>import java.io.BufferedReader;<br />
import java.io.InputStreamReader;<br />
import java.util.Hashtable;</p>
<p>public class BoniTwitterTest {</p>
<p> private static Hashtable&lt;String, AccessToken&gt; almacen = new Hashtable&lt;String, AccessToken&gt;();</p>
<p> public static void main(String args[]) throws Exception {</p>
<p> BufferedReader br = new BufferedReader(new InputStreamReader(System.in));<br />
 while (true) {<br />
 Twitter twitter = getTwitter();<br />
 System.out.println(&quot;Introduzca su nombre de usuario:&quot;);<br />
 String usuario = br.readLine();<br />
 AccessToken accessToken = almacen.get(usuario);<br />
 while (accessToken == null) {<br />
 RequestToken requestToken = twitter.getOAuthRequestToken();<br />
 System.out.println(&quot;Visita la siguiente página web y autoriza el acceso a tu cuenta:&quot;);<br />
 System.out.println(requestToken.getAuthorizationURL());<br />
 System.out.print(&quot;Una vez visitada, introduce el PIN y pulsa enter:&quot;);<br />
 String pin = br.readLine();<br />
 try {<br />
 if (pin.length() &gt; 0) {<br />
 accessToken = twitter.getOAuthAccessToken(requestToken, pin);<br />
 } else {<br />
 accessToken = requestToken.getAccessToken();<br />
 }<br />
 // Se guarda el token de autenticación para utilizar en un futuro<br />
 storeAccessToken(usuario, accessToken);<br />
 } catch (TwitterException te) {<br />
 if (401 == te.getStatusCode()) {<br />
 System.out.println(&quot;No ha sido posible obtener el token de autentiación&quot;);<br />
 } else {<br />
 te.printStackTrace();<br />
 }<br />
 twitter = getTwitter();<br />
 }<br />
 } // FIN del bucle WHILE que asegura la autenticación<br />
 twitter.setOAuthAccessToken(accessToken);<br />
 System.out.println(&quot;Introduzca su nuevo estado de Twitter o NADA si desea salir y pulse ENTER:&quot;);<br />
 String status = br.readLine();<br />
 if (status == null || status.length() == 0) {<br />
 System.out.println(&quot;Gracias por usar la aplicación. Adios !!!&quot;);<br />
 System.exit(0);<br />
 } else {<br />
 Status tstatus = twitter.updateStatus(status);<br />
 System.out.println(&quot;Se ha actualizado con exito el estado a [&quot; + tstatus.getText() + &quot;]&quot;);<br />
 }</p>
<p> } // FIN del bucle WHILE principal de la aplicación</p>
<p> }</p>
<p> /**<br />
 * Este metodo nos devolvera una instancia del objeto Twitter con la OAuyth Key y el OAuth Secret configurados<br />
 * @return una instancia del objeto Twitter<br />
 */<br />
 private static Twitter getTwitter() {<br />
 Twitter twitter = new Twitter();<br />
 twitter.setOAuthConsumer(&quot;OAuth Key&quot;, &quot;OAuth Secret&quot;);<br />
 return twitter;<br />
 }</p>
<p> /**<br />
 * Guarda el token de autenticación de un usuario en una Hashtable<br />
 * @param usuario el ID de usuario que servira como clave de guardado<br />
 * @param at el token de autenticación<br />
 */<br />
 private static void storeAccessToken(String usuario, AccessToken at) {<br />
 System.out.println(&quot;USUARIO TWITTER &quot; + usuario);<br />
 System.out.println(&quot;TOKEN &quot; + at.getToken());<br />
 System.out.println(&quot;TOKEN SECRET &quot; + at.getTokenSecret());<br />
 almacen.put(usuario, at);<br />
 }</p>
<p>}[/java]</p>
<p style="text-align: justify">
<li>Tenéis que sustituir las cadenas de texto  &#8216;<em>OAuth Key</em>&#8216; y &#8216;<em>OAuth Secret</em>&#8216; por las claves que os haya proporcionado <strong>Twitter </strong>al registrar vuestra aplicación.</li>
<li>¿Que qué hace este código? Pues, básicamente, comprobar si tenéis el <em>token </em>de validación de un usuario en el sistema y, si no lo tenéis, pediros que visitéis una web para obtener un código o <strong>PIN de autorización</strong> que demuestre que el usuario ha autorizado a tu aplicación a acceder a la API de <strong>Twitter </strong>en su nombre.
<div id="attachment_1379" class="wp-caption aligncenter" style="width: 668px"><img class="size-full wp-image-1379 " src="http://sixservix.com/blog/david/files/2009/12/twitter0.jpg" alt="Esta es la web en la que el usuario autoriza o no a tu aplicación para trabajar en tu nomre en Twitter" width="658" height="313" /><p class="wp-caption-text">Ésta es la web en la que el usuario autoriza o no a tu aplicación para trabajar en tu nombre en Twitter</p></div>
<p><div id="attachment_1380" class="wp-caption aligncenter" style="width: 668px"><img class="size-full wp-image-1379 " src="http://sixservix.com/blog/david/files/2009/12/twitter1.jpg" alt="Este es el PIN que te proporciona Twitter para que introduzcas en tu aplicación" width="658" height="313" /><p class="wp-caption-text">Éste es el PIN que te proporciona Twitter para que introduzcas en tu aplicación</p></div></li>
<li>Una vez que introduces el <strong>PIN</strong>, obtienes el <em>token</em> de autenticación y ya puedes solicitar los servicios de <strong>Twitter </strong>en nombre del usuario autenticado.</li>
<li>Nuestra pequeña aplicación, se limitará a solicitarnos el <em>status </em>con el que queremos actualizar la cuenta de <strong>Twitter </strong>del usuario autenticado.</li>
<li>Si actualizamos el <em>status </em>con la frase &#8216;<em>Actualizando el Estado de Twitter desde mi propia aplicación Java</em>&#8216; podremos comprobar como en la cuenta de <strong>Twitter </strong>del usuario -en este caso, yo- el estado se ha modificado:
<p><div id="attachment_1387" class="wp-caption aligncenter" style="width: 639px"><img class="size-full wp-image-1387" src="http://sixservix.com/blog/david/files/2009/12/twitter2.jpg" alt="twitter2" width="629" height="367" /><p class="wp-caption-text">Fijaos en que pone que el estado se ha modificado desde &#39;Prueba David&#39; el nombre de mi aplicación registrada</p></div></li>
</ol>
<p style="text-align: justify">
<p style="text-align: justify">Si accedéis a la API de <strong>Twitter </strong>desde una aplicación web, podréis redirigir el flujo de la aplicación a la página de autenticación y configurar dicha página para que invoque una de vuestras páginas mediante <em>callback</em>. Mola ¿verdad? Se autentican en <strong>Twitter </strong>y continúan en tu aplicación proporcionándote el <strong>PIN </strong>de autenticación de paso.</p>
<p style="text-align: justify">Evidentemente <strong>esta aplicación es una chorrez como un piano</strong>, pero es un ejemplo claro y sencillo sobre cómo registrar una aplicación en Twitter, cómo autenticar a un usuario mediante <strong>OAuth </strong>y cómo manejar su <em>pool</em> de servicios<strong> </strong>en nombre de ese usuario. A partir de aquí, enriquecer y hacer crecer esta mini aplicación, depende de vosotros. Seguro que se os ocurren un montón de ideas, simplemente estudiando las posibilidades de la API, pero os voy a proponer algo: ¿No creéis que sería interesante para un departamento de marketing una aplicación que buscara menciones de los productos de una compañía en los <em>tweets </em>de la gente y que guardara los IDs de la gente para, posteriormente mandarles <a href="http://help.twitter.com/forums/82075/entries/72739" target="_blank"><em>tweets </em>de respuesta</a> con ofertas o comunicados? Yo, al menos, conozco a más de un <em>gurú del marketing</em> muuuy interesado :)</p>
<p style="text-align: justify">Espero que este humilde tutorial os haya servido de ayuda y os anime a crear la nueva <em>killer application</em> de esa pequeña gran plataforma llamada <strong>Twitter</strong>.</p>
<p style="text-align: justify"><span style="text-decoration: underline">Algunos <em>links </em>de interés</span></p>
<p style="text-align: justify"><span style="color: #008000"><strong>API REST DE TWITTER:</strong></span> <a href="http://apiwiki.twitter.com/Twitter-API-Documentation" target="_blank">http://apiwiki.twitter.com/Twitter-API-Documentation</a></p>
<p style="text-align: justify"><span style="color: #008000"><strong>API JAVA TWITTER4J:</strong></span> <a href="http://yusuke.homeip.net/twitter4j/en/javadoc/index.html" target="_blank">http://yusuke.homeip.net/twitter4j/en/javadoc/index.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2009/12/15/twitter-y-java/feed/</wfw:commentRss>
		<slash:comments>728</slash:comments>
		</item>
		<item>
		<title>Explicando REST a mi madre</title>
		<link>http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/</link>
		<comments>http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 05:30:14 +0000</pubDate>
		<dc:creator>David Bonilla</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[webservices]]></category>

		<guid isPermaLink="false">http://sixservix.com/blog/david/?p=186</guid>
		<description><![CDATA[Si mamá, desde hace ya un buen tiempo, cuando vienes a visitarme a casa, no paras de leer en la pantalla de mi ordenador, en los papeles que tengo por ahí sueltos,  eso de REST. Y como no acabas de creerte que el término no tiene nada que ver con colchones, voy a intentar explicártelo. [...]


Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2011/02/16/http-access-control-rest/' rel='bookmark' title='Permanent Link: HTTP Access Control: programando REST de VERDAD'>HTTP Access Control: programando REST de VERDAD</a> <small>La mayoría de los que hablan de REST son un...</small></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify"><img class="alignleft size-medium wp-image-279" style="margin: 5px 10px" src="http://sixservix.com/blog/david/files/2009/09/nerd-223x300.jpg" alt="CB009957" width="161" height="216" />Si mamá, desde hace ya un buen tiempo, cuando vienes a visitarme a casa, no paras de leer en la pantalla de mi ordenador, en los papeles que tengo por ahí sueltos,  eso de <strong>REST</strong>. Y como no acabas de creerte que el término <a href="http://www.bodyrestmattress.com" target="_blank">no tiene nada que ver con colchones,</a> voy a intentar explicártelo.</p>
<p style="text-align: justify">Puedes encontrar artículos en la web que describen <a href="http://www.dosideas.com/java/314-introduccion-a-los-servicios-web-restful.html" target="_blank">REST en castellano de pe a pa</a>, e incluso completísimos tutoriales sobre <a href="http://www.gruposp2p.org/wiki/index.php/Arranque_de_un_proyecto_con_Rest,_JPA_y_Maven" target="_blank">como montar tu primera aplicación REST con java</a>, pero quizás todo sea demasiado teórico y complejo para alguien que, como tú, busca una primera aproximación y no tiene porqué tener necesariamente mucha idea de Web Services, SOA o HTTP. Voy a intentar explicártelo muy claro y con ejemplos, como a ti te gusta.</p>
<p style="text-align: justify">Tranquila mamá, no te sientas mal por no tener muy claro esos conceptos. Hay muchos arquitectos de software y desarrolladores que tampoco los tienen. A lo mejor a ellos también les interesaría escuchar todo esto que te cuento. Es fácil, creo que en <strong>menos de 5 minutos</strong> tú y ellos os habréis hecho con ello.<span id="more-186"></span></p>
<p style="text-align: justify">Lo primero que tienes que tener claro es que <span style="text-decoration: underline">REST no es una tecnología sino una arquitectura</span>. Para que lo entiendas, no es algo que solucione cosas sino una forma de diseñar algo que solucione cosas. ¿Y qué tiene de especial esta <em>arquitectura </em>para que todo el mundo hable de ella? Intentaré explicártelo.</p>
<ol style="text-align: justify">
<li><strong>Diseñas tu aplicación exponiendo </strong><strong>recursos no funcionalidades</strong>. Sí, ya no programo páginas web que tengan direcciones como<em> www.mipagina.com/crearCosa</em> o <em>www.mipagina.com/consultarCosa</em>. Ahora sólo tengo <em>www.mipagina.com/cosas </em>o <em>www.mipagina.com/cosas/12345/atributos</em>. Sí te das cuenta, es como si tuviera mis recursos ordenados en directorios. Y sí, sé lo que te estás preguntando: si sólo hay un <em>www.mipagina.com/cosas </em>¿cómo sé si mis usuarios intentan crear una cosa o simplemente consultarla? Ahora te explico, ten un poco de paciencia.</li>
<li><strong>Utiliza los métodos del protocolo HTTP de manera explicita</strong>. HTTP es un protocolo de comunicación que hace que Internet funcione. ¿No te has dado cuenta de que cuando escribes una dirección en el navegador pone <em>http://</em> por delante de la dirección? Bueno, pues eso es porque te estás comunicando mediante ese protocolo. <span style="text-decoration: underline">Lo que no tanta gente sabe, incluidos muchos programadores</span>, es que el protocolo HTTP tiene un montón de métodos definidos en su especificación: GET, POST, PUT, DELETE&#8230; y que cada uno de ellos tiene un propósito específico aunque, a veces, te reconozco que los desarrolladores nos lo saltamos a la torera.  No te suena de nada ¿verdad? Eso es porque <span style="text-decoration: underline">la mayoría de los navegadores utilizan el método GET por defecto en las peticiones HTTP</span>, excepto que le indiquemos especificamente otra cosa en nuestras páginas web. Así , cuando escribimos el nombre de una página en la barra de direcciones de un navegador, la invocamos con el método GET. ¿Que por qué te he soltado este <em>ladrillo</em> que no te interesa? Espera un poco, ya verás como todo empieza a encajar.</li>
<li><strong>Mapea los métodos del protocolo HTTP a las operaciones a realizar sobre un recurso</strong>. Fíjate que bueno, si te conectas a un recurso -una página web, para que lo entiendas- invocando el método GET, por ejemplo, yo sé que es lo que quieres porque <span style="text-decoration: underline">el método GET se utiliza para consultar un recurso</span>. Del mismo modo, al resto de los métodos principales de HTTP se les mapea una operación específica. Así, POST se utiliza para crear un recurso, PUT para actualizarlo y DELETE para borrarlo, evidentemente. Si, por ejemplo, solicitas la página  <em>www.mipagina.com/cosas</em> con el parámetro id=2345 y el método GET, mi aplicación REST te devolverá la cosa con id=2345. Sin embargo, si repites la misma solicitud con el mismo parámetro pero con el método DELETE lo que  conseguirás es borrar la cosa con id=2345.  ¡Tacháaan! ¿A que ahora parece todo más claro?</li>
<li><strong>Transfiere XML, JSON o XTHML</strong>. No te voy a calentar la cabeza mamá explicándote qué es cada cosa. Confía en mi. Basta con que sepas que son cosas que se pueden consumir e interpretar desde un navegador y convertir en una de esas bonitas páginas web que tanto te gustan. Sólo para que lo sepas, cuando te digo que te <em>devuelve</em> una <em>cosa</em>, me refiero a que te devuelve algo como esto:</li>
</ol>
<pre style="padding-left: 60px;text-align: justify">&lt;cosa&gt;</pre>
<pre style="padding-left: 60px;text-align: justify">    &lt;id&gt;2345&lt;/id&gt;</pre>
<pre style="padding-left: 60px;text-align: justify">    &lt;nombre&gt;cosa misteriosa&lt;/nombre&gt;</pre>
<pre style="padding-left: 60px;text-align: justify">&lt;/cosa&gt;</pre>
<p style="text-align: justify">
<p style="text-align: justify">Sé que tendrás algunas dudas. Creo que podré adivinar alguna de ellas :)</p>
<ul style="text-align: justify">
<li><strong>¿Cómo le indico eso del id? ¿Sólo puedo mandar un parámetro? Y lo de los métodos HTTP ¿Cómo se cambian? </strong>Bueno, a ver, el id es un parámetro que envías en tu petición. Y, claro, puedes mandar todos los que quieras. Si lo piensas bien, cuando rellenas un formulario en una página web no estás haciendo más que mandar un montón de parámetros -uno por cada campo del formulario- sin límite alguno. Usando REST no haces mas que navegar así que, SÍ, puedes enviar lo que quieras. Respecto a lo de cambiar el método HTTP a utilizar bueno&#8230; eso no es tan sencillo. <span style="text-decoration: underline">No vas a poder hacerlo directamente desde tu navegador</span> pero, <span style="text-decoration: underline">los programadores de páginas HTML sí tienen la posibilidad de hacerlo</span>. Si llegas a una página web diseñada para utilizar con una aplicación REST y, por ejemplo, ves un botón &#8220;Eliminar <em>Cosa</em>&#8220;, seguro que vas a hacer una petición con el método DELETE</li>
<li><strong>¿Y si no le paso ningún parámetro?</strong> No pasa nada. Si, por ejemplo, haces una petición GET a <em>www.mipagina.com/cosas </em>sin pasar ningún parámetro, probablemente conseguirás que una aplicación REST te devuelva un montón de <em>enlaces</em> a todas las cosas que esten relacionadas con dicho recurso. Por ejemplo, una lista de cosas (<em>www.mipagina.com/cosas/0001, </em><em>www.mipagina.com/cosas/0002</em>&#8230;). Si lo piensas bien <span style="text-decoration: underline">todo lo que te devuelve son a su vez enlaces REST que puedes reutilizar haciendo nueva petición con el método que te interese</span> contra dichos enlaces. ¡Genial! ¿Verdad?</li>
<li><strong>¿Y todos los recursos implementan todos los métodos?</strong> Pues, realmente NO. De hecho, hay otro método de HTTP, <strong>OPTIONS</strong>, cuya finalidad es obtener una lista de los métodos soportados por un recurso. A lo mejor, el programador de una aplicación REST quiere permitirte consultar una determinado información pero no quiere que la actualices.</li>
<li><strong>Y entonces ¿cualquiera puede borrar cosas de tu aplicación?</strong> No. Puedes identificar a tus usuarios con los métodos de autenticación que te proporciona cualquier servidor HTTP o incluso utilizar <a href="http://developers.sun.com/identity/reference/techart/restwebservices.html" target="_blank">cosas más sofisticadas</a>.  No te preocupes, puedes conseguir que sólo acceda a tu aplicación REST quien tú quieras.</li>
</ul>
<p style="text-align: justify">Como ya te he dicho REST sólo es una arquitectura, no una tecnología. Tienes que evaluar bien si te interesa o no utilizarla. Si te interesa conocer cuáles son algunas de sus ventajas, te explicaré alguna de las más importantes:</p>
<ul style="text-align: justify">
<li><strong>El método HTTP GET y el cacheo</strong>. Muchos <em>proxies </em>y <em>firewalls </em>-ordenadores que gestionan una red- suelen cachear las peticiones GET. Que, ¿qué es eso de cachear? Pues guardarse una copia de la página que solicitas con tu método GET y, si otro ordenador de tu misma red solicita la misma página, devolver esa copia mucho más rápido que si tuviera que obtener la página de nuevo.</li>
<li><strong>No utiliza estado de sesión</strong>. A ver como te explico esto&#8230; ¿recuerdas cuando me pediste que te enseñara a comprar por Internet y estuvimos comprando libros? Esos libros se iban acumulando en un <em>carrito de la compra</em> y, al final, pagamos con tarjeta de crédito. Bueno, ese carrito de la compra existía porque la página web nos identificó durante toda nuestra<em> sesión de trabajo</em> y, es genial. Lo que pasa es que, al final, somos muchos los que compramos libros y eso puede acabar sobrecargando los servidores donde se alojan las páginas web. Cuando 5 están comprando libros no hay problema pero, cuando son 5000&#8230; la cosa cambia. El hecho de que REST no mantenga estado de sesión quiere decir que en nuestras peticiones de recursos y en las respuestas del servidor tiene que viajar toda la información necesaria. Nada se guarda en la memoria del servidor.</li>
<li><strong>Puedes distribuir una API completa de tu aplicación en un fichero de javascript</strong>. Mmmm&#8230; para que lo entiendas de una forma sencilla ¿conoces <a href="http://www.facebook.com" target="_blank">Facebook</a>, no?. Bueno, pues lo bueno de  <strong>Facebook</strong>, lo que ha hecho que triunfe tanto es que <span style="text-decoration: underline">ha posibilitado que terceros creen aplicaciones y las incrusten en la página</span>. Casi todas esas aplicaciones te permiten interactuar con tus contactos de Facebook, pero dichas aplicaciones no tienen acceso directo a la BBDD de la página web, sino a una API, un conjunto de utilidades, que proporciona Facebook y que permiten acceder, por ejemplo, a los amigos del usuario que está ejecutando la aplicación. Créeme, <span style="text-decoration: underline">eso es una aplicación REST como una casa</span>. ¿Te imaginas que Facebook tuviera que distribuir por ahí la ruta de acceso a su BBDD? ¿Te imaginas los problemas de seguridad y escalabilidad que supondría?</li>
</ul>
<p style="text-align: justify">En fin mamá, que REST está muy bien, pero es una manera más de solucionar las cosas, ni más ni menos. Por ejemplo, no tengo muy claro que fuera la arquitectura más adecuada para ese ejemplo que te he puesto del <em>carrito de la compra</em>, aunque sí para muchos otros supuestos.</p>
<p style="text-align: justify">La gente está muy ilusionada con el tema, sobre todo como <span style="text-decoration: underline">una apuesta para conseguir de una manera sencilla, rápida y flexible la interoperabilidad entre distintas aplicaciones escritas en distintos lenguajes</span>. Antes todo el mundo pensaba que los <strong>webservices </strong>eran el único medio válido para conseguir esto de una manera eficiente pero, ahora, hay bastante gente que lo pone en duda porque, la verdad, la especificación donde te explica cómo implementarte por entero un webservice, cómo publicarlo y cómo consumirlo es&#8230; un <strong>poco dura</strong> y pffff&#8230; ¡no creo que consiguiera explicártela en 5 minutos como he hecho con esto del REST! Y eso es lo bueno de esta arquitectura. Mamá, si tú has conseguido entenderlo, creo que cualquier desarrollador lo hará.</p>
<p style="text-align: justify">


<p>Artículos relacionados:<ol><li><a href='http://sixservix.com/blog/david/2011/02/16/http-access-control-rest/' rel='bookmark' title='Permanent Link: HTTP Access Control: programando REST de VERDAD'>HTTP Access Control: programando REST de VERDAD</a> <small>La mayoría de los que hablan de REST son un...</small></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://sixservix.com/blog/david/2009/09/30/explicando-rest-a-mam/feed/</wfw:commentRss>
		<slash:comments>500</slash:comments>
		</item>
	</channel>
</rss>

