RESTful... la forma más ligera de hacer WebServices (Parte 1)
Quienes hayan usado SOAP para WebService, sabrán que es bien fácil de diseñar, pero algo complicado de consumir: se necesita toda una API para construir los clientes utilizando el WSDL. Por ejemplo, para PHP se necesita de la biblioteca NuSOAP. Entonces, para lograr el concepto de "lenguaje único XML" es un dolor de cabeza. Y más aún si el cliente es tan simple como JavaScript, manejar XML de SOAP provocaría suicidos masivos... o no usar WebServices.
Además, con SOAP se permite crear un solo servicio y ponerle varios métodos. Esto puede llevar a un mal diseño del servicio ya que podría tener un servicio que haga de todo: por ejemplo, un servicio de manejo de Clientes que permita también manejar Proveedores.
RESTful es una propuesta muy interesante de Roy Fielding que permite manejar los servicios web con métodos definidos, manteniendo la simpleza del protocolo como XML, pero que cada servicio sea identificado únicamente con un solo URI.
En este post veremos cómo crear un Servicio RESTful usando NetBeans, y haremos crecer de poco a poco nuestro ejemplo... desde hacer operaciones sencillas, hasta manejar estructuras complejas.
Cabe destacar que los servicios de las redes sociales como Flickr, Twitter, Facebook, etc son basados en RESTful.
Para este ejemplo usaremos NetBeans 6.9.1, y GlassFish v3.0.1, ya que usaremos las características de Java EE6. Con GlassFish v.2 igual funciona, y NetBeans ayuda en ello,
Para comenzar, debemos entender que necesitamos de una clase para manejar un servicio. En esta clase solo pueden haber máximo cuatro métodos públicos que son ejecutados por los cuatro métodos HTTP disponibles para RESTful:
Luego, crearemos una clase común y silvestre, llamada
A esta clase se puede crear su TestCase para asegurarnos que funciona correctamente. Notemos que hasta ahora no hemos hecho nada REST. La diversión comienza aquí:
Agreguemos la notación
Luego, seguido al
Utilizaremos el dado por defecto (
Nota de actualización: Para NetBeans 7.3, la opción de crear el recurso REST cambia. Mirar aquí RESTful con NetBeans 7.3
Nota: En GlassFish v2 (Java EE 5) solo existirán dos opciones
Y con esto, nuestra clase ya es un recurso REST.
Pero aún este recurso no tiene métodos. Ahora veremos cómo convertir nuestro método convencional en un método REST.
Para ello agregamos la anotación
Y con esto, nuestro recurso ya tiene un método.
Antes de continuar, los valores que se reciben desde el recurso REST deben ser objetos. Por tanto, nuestro método debe cambiar un poco para que no devuelva un
Además, debemos indicar que el parámetro
Para ello usaremos la notación
El nombre del parámetro de la cadena query podría ser diferente al del método java.
Pero si se hace eso, se debería recordar que para accederlo via URL debe ser con ese mismo nombre
Pero para evitar problemas, usaremos el mismo nombre. Y en caso de ser necesario, podemos cambiar el nombre. Eso ya queda a criterio del diseñador de la aplicación.
Aquí propondré tres maneras de probar el recurso REST. El primero es el más fácil, usando el URL. Bastará con abrir nuestro navegador y escribir el URL del proyecto:
Este URL está compuesto de lo siguiente:
Y ese es el resultado. Quizás me digan "hey, pero esto también lo puedo hacer con un servlet". Pues sí, pero no es lo mismo, ya que el Servlet puede guardar variables de sesión, y aquí en REST no... en Servlet se puede formatear en un HTML, pero aquí en REST no, porque lo que debe devolver es solo dato.
La segunda manera que muestro cómo probar este recurso REST es usando un formulario HTML. Escribamos lo siguiente en el
El resultado saldrá en otra página.
Y la tercera forma (que es la más profesional) es usando el NetBeans.
Hacemos clic derecho sobre el ícono del proyecto y seleccionamos "Test RESTful WebService".
Con esto, el IDE creará una página local que accederá al WADL de la aplicación y se mostrará en el navegador web.
El WADL es análogo al WSDL de SOAP
Luego, podemos seleccionar del panel izquierdo el recurso que está disponible (en este caso "factorial")...
... y vemos que nos muestra cuales son los parámetros (solo base) que están disponibles para este recurso. Probamos escribiendo valores en el parámetro, y hacemos clic en "Test".
Crearemos una página html al que llamaremos test-jquery.html. Y ahí pondremos lo siguiente.
Esta HTML funciona desde Firefox cuando se ejecuta desde el NetBeans,
y funciona en IExplorer si se ejecuta localmente (o sea, abriéndolo desde el explorador de archivos y activar el filtro de ActiveX que advierte el IE).
Para nuestro ejemplo, este es
http://localhost:8080/SimpleRESTweb/resources/application.wadl
Podemos abrirlo desde el navegador y se nos mostrará un XML que contiene la definición de los recursos (
Ahora bien, este URL del WADL lo vamos a necesitar para registrarlo en el NetBeans. En el IDE vayamos al panel de servicios (Ctrl+5) y hacemos clic derecho sobre el nodo "Web Services" y seleccionamos "Add Web Service..."
Luego, en la entrada de URL, pegamos la dirección del WADL. Y como nombre de paquete ponemos
Y listo, ya tendremos registrado el WebService en nuestro IDE.
Esto nos permitirá utilizar este servicio en cualquiera de nuestras aplicaciones. Por ejemplo, ahora, en Java.
Hagamos un nuevo proyecto llamado
Ahora, crearemos un nuevo archivo (Ctrl+N) y seleccionamos la categoría "Web Services" y el tipo de archivo "RESTful Java Client"
Luego, en el siguiente paso, pongamos como nombre de la clase
... y hagamos clic en "Browse" para seleccionar el WebService que acabamos de registrar.
y clic en "Finish". Listo, el IDE nos creará la clase
Ahora, ¿cómo se consume esto?... en nuestra clase Java solo debemos instanciar la clase, pasarle el parámetro y recibir el valor. Fácil
http://kenai.com/projects/apuntes/downloads/download/Simple%2520RESTful%252FSimpleRESTweb.tar.gz
y el ejemplo de cliente REST en Java se puede descargar de aquí
http://kenai.com/projects/apuntes/downloads/download/Simple%2520RESTful%252FSimpleRESTClientJavaApp.tar.gz
Además, con SOAP se permite crear un solo servicio y ponerle varios métodos. Esto puede llevar a un mal diseño del servicio ya que podría tener un servicio que haga de todo: por ejemplo, un servicio de manejo de Clientes que permita también manejar Proveedores.
RESTful es una propuesta muy interesante de Roy Fielding que permite manejar los servicios web con métodos definidos, manteniendo la simpleza del protocolo como XML, pero que cada servicio sea identificado únicamente con un solo URI.
En este post veremos cómo crear un Servicio RESTful usando NetBeans, y haremos crecer de poco a poco nuestro ejemplo... desde hacer operaciones sencillas, hasta manejar estructuras complejas.
Cabe destacar que los servicios de las redes sociales como Flickr, Twitter, Facebook, etc son basados en RESTful.
Para este ejemplo usaremos NetBeans 6.9.1, y GlassFish v3.0.1, ya que usaremos las características de Java EE6. Con GlassFish v.2 igual funciona, y NetBeans ayuda en ello,
Para comenzar, debemos entender que necesitamos de una clase para manejar un servicio. En esta clase solo pueden haber máximo cuatro métodos públicos que son ejecutados por los cuatro métodos HTTP disponibles para RESTful:
- GET
- POST
- DELETE
- PUT
<form method="post" />
) ¿Tienen algo que ver? Sí, y lo veremos poco a poco. Cada uno de estos métodos determina la acción que hará el REST sobre nuestra aplicación. No deben haber más de un GET o POST o DELETE o PUT, solo tiene que haber uno de cada método. Cada uno tiene una tarea especifica:- GET: Para obtener un valor. Puede ser un listado de objetos
- POST: Para guardar un nuevo objeto (instancia de identidada) en la aplicación
- DELETE: Para eliminar un objeto (instancia de identidad)
- PUT: Para actualizar un objeto.
Creando proyecto y configurando REST
Crearemos un proyecto web común y silvestre en NetBeans. Yo crearé uno llamadoSimpleRESTweb
. Este proyecto hará un simple cálculo de factorial. (Aunque a muchos no les guste, comenzaré siempre con una calculadora ya que es el clásico ejemplo de Entrada->Procesamiento->Salida.. lo demás, usando entidades, bases de datos, etc.. es lo mismo, solo que utiliza más variables)Luego, crearemos una clase común y silvestre, llamada
FactorialResource
. Tendrá (por ahora) un método llamado factorial()
public class FactorialResource {
public long factorial(long base) {
if (base >= 1) {
return factorial(base - 1) * base;
}
return 1;
}
}
A esta clase se puede crear su TestCase para asegurarnos que funciona correctamente. Notemos que hasta ahora no hemos hecho nada REST. La diversión comienza aquí:
Agreguemos la notación
@Stateless
al inicio de la clase. Esto convierte automáticamente a nuestra clase en un EJBLuego, seguido al
@Stateless
agregamos la anotación @Path("/factorial")
Esto indica que este recurso será accedido desde la ruta "/factorial" via web. Ahora, guardemos el archivo... y en ese mismo momento, el NetBeans detectará de que se ha creado un recurso REST, entonces pedirá activar esta característica en la aplicación... por tanto pedirá dónde estará activado todos los recursos REST. Utilizaremos el dado por defecto (
/resources
). Clic en Ok.Nota de actualización: Para NetBeans 7.3, la opción de crear el recurso REST cambia. Mirar aquí RESTful con NetBeans 7.3
Nota: En GlassFish v2 (Java EE 5) solo existirán dos opciones
Y con esto, nuestra clase ya es un recurso REST.
Pero aún este recurso no tiene métodos. Ahora veremos cómo convertir nuestro método convencional en un método REST.
Creando un método REST
Recordemos que solo podemos crear un método de tipo GET,POST,PUT y DELETE. Y como el métodofactorial
nos deberá devolver un solo valor según el parámetro que le especificamos, usaremos el tipo GET.Para ello agregamos la anotación
@GET
antes del método.Y con esto, nuestro recurso ya tiene un método.
Antes de continuar, los valores que se reciben desde el recurso REST deben ser objetos. Por tanto, nuestro método debe cambiar un poco para que no devuelva un
long
, sino un java.lang.String
.Además, debemos indicar que el parámetro
base
del método Java factorial
será recibido via URL con el nombre base
. Es decir, se llamará al URL así..../factorial?base=5
Para ello usaremos la notación
@QueryParam
antes de la declaración del parámetro y ponemos el nombre de la cadena query.
@Stateless
@Path("/factorial")
public class FactorialResource {
@GET
public String factorial(@QueryParam("base") long base) {
return Long.toString($factorial(base));
}
long $factorial(long base) {
if (base >= 1) {
return $factorial(base - 1) * base;
}
return 1;
}
}
El nombre del parámetro de la cadena query podría ser diferente al del método java.
//....
@GET
public String factorial(@QueryParam("numero") long base) {
//....
Pero si se hace eso, se debería recordar que para accederlo via URL debe ser con ese mismo nombre
..../factorial?numero=5
Pero para evitar problemas, usaremos el mismo nombre. Y en caso de ser necesario, podemos cambiar el nombre. Eso ya queda a criterio del diseñador de la aplicación.
Probando la aplicación
Pues bien, ahora guardemos el proyecto, hagamos clic derecho sobre el ícono de proyecto y seleccionamos "Deploy". Esperamos a que se compile el proyecto, se ejecute el GlassFish y se despliegue.Aquí propondré tres maneras de probar el recurso REST. El primero es el más fácil, usando el URL. Bastará con abrir nuestro navegador y escribir el URL del proyecto:
http://localhost:8080/SimpleRESTweb/resources/factorial?base=10
Este URL está compuesto de lo siguiente:
- SimpleRESTweb: El contexto de la aplicación. Que generalmente es el nombre del proyecto.
- resources: Ubicación de los recursos REST de la aplicación. Este nombre nos lo pidió el NetBeans cuando guardamos la clase Java por primera vez con la notación
@Path
ya que detectó que tenía recursos REST. Si se desea cambiar esta ruta, hagamos clic derecho en el nodo "RESTful Web Services" del proyecto y seleccionando "REST Resources Configuration" - factorial: Es el nombre de nuestro recurso (Definido por la anotación
@Path
) - base: Es el parámetro del recurso. Justamente es una cadena Query.
Y ese es el resultado. Quizás me digan "hey, pero esto también lo puedo hacer con un servlet". Pues sí, pero no es lo mismo, ya que el Servlet puede guardar variables de sesión, y aquí en REST no... en Servlet se puede formatear en un HTML, pero aquí en REST no, porque lo que debe devolver es solo dato.
La segunda manera que muestro cómo probar este recurso REST es usando un formulario HTML. Escribamos lo siguiente en el
index.jsp
<body>
<h1>Calculando factorial</h1>
<form action="resources/factorial">
Base: <input name="base" type="text" />
<button>Calcular</button>
</form>
</body>
El resultado saldrá en otra página.
Y la tercera forma (que es la más profesional) es usando el NetBeans.
Hacemos clic derecho sobre el ícono del proyecto y seleccionamos "Test RESTful WebService".
Con esto, el IDE creará una página local que accederá al WADL de la aplicación y se mostrará en el navegador web.
El WADL es análogo al WSDL de SOAP
Luego, podemos seleccionar del panel izquierdo el recurso que está disponible (en este caso "factorial")...
... y vemos que nos muestra cuales son los parámetros (solo base) que están disponibles para este recurso. Probamos escribiendo valores en el parámetro, y hacemos clic en "Test".
Consumiendo REST
Todo servicio web no es útil si no se sabe cómo consumir. En este post mostraremos cómo consumir este simple REST. En los siguientes post realizaremos recursos que utilizan objetos complejos.Usando JavaScript
Para consumir desde JavaScript, se debería utilizar la técnica AJAX. Y en vez de hacer toda la biblioteca de consumir AJAX con JavaScript, mejor usamos algo ya hecho... como el jQuery.Crearemos una página html al que llamaremos test-jquery.html. Y ahí pondremos lo siguiente.
<html>
<head>
<title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h2>Calcular factorial</h2>
Número:<input type="text" name="base" id="base"/>
<button type="button" id="calcularBtn">Calcular</button>
<div id="resultado">
Resultado: <span></span>
</div>
<script type="text/javascript">
jQuery("#calcularBtn").click(function(){
var base = jQuery("#base").val();
jQuery.get("http://localhost:8080/SimpleRESTweb/resources/factorial",{
base:base
},function(resultado){
jQuery("#resultado span").text(resultado)
})
})
</script>
</body>
</html>
Esta HTML funciona desde Firefox cuando se ejecuta desde el NetBeans,
y funciona en IExplorer si se ejecuta localmente (o sea, abriéndolo desde el explorador de archivos y activar el filtro de ActiveX que advierte el IE).
Usando Java
Con NetBeans más el complemento Jersey, se nos hace muy fácil consumir servicios REST. Para integrarlo con el IDE, necesitamos registrar el WADL. Esta URL lo podemos obtener así: http://host:puerto/contexto-web/resources/application.wadlPara nuestro ejemplo, este es
http://localhost:8080/SimpleRESTweb/resources/application.wadl
Podemos abrirlo desde el navegador y se nos mostrará un XML que contiene la definición de los recursos (
/factorial
) y los parámetros de cada método. En este caso hay un método GET y tiene como parámetro un long.Ahora bien, este URL del WADL lo vamos a necesitar para registrarlo en el NetBeans. En el IDE vayamos al panel de servicios (Ctrl+5) y hacemos clic derecho sobre el nodo "Web Services" y seleccionamos "Add Web Service..."
Luego, en la entrada de URL, pegamos la dirección del WADL. Y como nombre de paquete ponemos
simplerest
. Y listo, ya tendremos registrado el WebService en nuestro IDE.
Esto nos permitirá utilizar este servicio en cualquiera de nuestras aplicaciones. Por ejemplo, ahora, en Java.
Hagamos un nuevo proyecto llamado
SimpleRESTClientJavaApp
.Ahora, crearemos un nuevo archivo (Ctrl+N) y seleccionamos la categoría "Web Services" y el tipo de archivo "RESTful Java Client"
Luego, en el siguiente paso, pongamos como nombre de la clase
FactorialClient
, dentro de la opción "Select the REST resource" seleccionemos la opción "IDE Registered" ... y hagamos clic en "Browse" para seleccionar el WebService que acabamos de registrar.
y clic en "Finish". Listo, el IDE nos creará la clase
FactorialClient
que contendrá los recursos necesarios para acceder al servicio REST.Ahora, ¿cómo se consume esto?... en nuestra clase Java solo debemos instanciar la clase, pasarle el parámetro y recibir el valor. Fácil
FactorialClient client = new FactorialClient();
long base = 15;
String resultado = client.factorial(String.class, String.valueOf(base));
System.out.println("Resultado: " + resultado);
Código fuente
El ejemplo del servidor REST se encuentra aquíhttp://kenai.com/projects/apuntes/downloads/download/Simple%2520RESTful%252FSimpleRESTweb.tar.gz
y el ejemplo de cliente REST en Java se puede descargar de aquí
http://kenai.com/projects/apuntes/downloads/download/Simple%2520RESTful%252FSimpleRESTClientJavaApp.tar.gz
Felicitaciones Diego, este ejemplo ma ha ayudado mucho para seguir aclarando el concepto REST que aun se me confunde en ocasiones. Me queda una duda para consumirlo desde J2ME, SWING y JPA habría que hacer algún cambio?
ردحذفHola Fernando
ردحذفEl consumo desde Swing es lo mismo que está el ejemplo con Java. El ejemplo que está para descargar utiliza Swing.
El JPA estará del lado del Servidor. En los siguientes post mostraré como crear REST con objetos.
Con J2ME sería interesante utilizar. Ya que este tipo de webservice es más ligero, no se necesitaría mucha biblioteca adicional. Estaba haciendo con JavaFX pero no me alcanzó el tiempo. Para el siguiente post pondré con más ejemplos, como con PHP.
Saludos
Hola gracias por este tutorial es de lo mejor que eh encontrado en linea, tengo un problema baje tu aplicación y eh hecho otros ejemplos pero cuando ajo testrestful la pagina no me muestra ningun nodo en la parte izquierda y doy click sobre el link WADL o la pagina queda en blanco sabras a que se debe, ya instale otro netbeans otro glassfish y no me muestra nada o.o?? y la consola no me dice nada
ردحذفHola ya encontre lo que paso.
ردحذفEstoy usando chrome y en chrome no funciona por ahi encontre que asta la siguiente vercion mejorarian este bug.
Hola Diego, muchas felicidades, el tutorial es excelente y es la mejor explicación práctica que encontré en la red. Gracias por el aporte!
ردحذفDiego favor podrias ayudarnos con un ejemplo de como usar rest con niveles de autentificacion y eso de las apis keys
ردحذفno tendrian este mismo ejemplo usando SOAP, se los agradeceria mucho, muy buen tutorial
ردحذفMuchas Gracias Diego, este es un ejemplo muy completo
ردحذفsobre este tema.
Te lo puedo afirmar ya que en la web he encontrado
un montón de cochinadas de gente que no sabe ni de lo
que esta hablando, solo copian y pegan código de un lado
para otro.
Muchas Gracias!!!
Buenas Diego, excelente ejemplo, aclaro mucho mis dudas, ahora se me presente un problema, como poder consumir el web service desde .Net, utilizando c# como lenguaje. Quisiera generar la clase proxy desde el WADL, pero no encuentro alguna herramienta que la genere. O es que no sé si es posible generar dicha clase desde WADL.
ردحذفHola, tengo una duda, ¿qué librerías te ayudan al desarrollo del servicio REST? es decir, aquellas que te dan funcionalidades como las directivas @Stateless o @Path, ¿las proporciona de base el NetBeans? ¿funcionaría igual en un Eclipse JEE?
ردحذفAlguien sabe si existe un plugin para eclipse que facilite/automatice la creación de estos servicios y sus clientes?
Muchas gracias.
Saludos,
ردحذفEstuve siguiendo el tuto paso a paso y me pareció muy bueno pero tuve algunas dificultades. Te dejo algunas observaciones que pueden servir para mejorarlo.
Buscando en la web ejemplos se puede encontrar mucho y en algunos ejemplos dicen que uno debe indicar que Framework va a usar cuando NetBeans lo pregunta. Bueno, aquí fue mi problema. Yo le dije a NetBeans que incluyera el Spring Framework, seguí todos tus pasos, y al final no realizaba Deployment por falta de una biblioteca .jar llamada aopalliance necesaria para hacer Deploy bajo Spring.
Encontré dos soluciones, no hacerlo bajo ningun framework o descargar e incluir el aopalliance.jar en el proyecto.
Gracias por el tuto me ayudo bastante.
Hola Sebastián
حذفGracias por tu comentario. En efecto, hay varias implementaciones que ayudan a hacer lo mismo. Es más, uno puede hacerse uno usando nada más que servlets. Yo he usado el que viene incluido en NetBeans que está basado de Jersey. Este post tiene algo más de dos años y pues habrán muchas mejoras. Además, en el Java EE 7 tendrá mejoras incluyendo RESTful.
Gracias por tu aporte.
Vientos!!! esta padrísima esta tecnología para desarrollo de WebServices. Y muy bien explicada. Cuanto tenga dudas te preguntare jejejeje
ردحذفOk MSC :) gracias.. y cuando yo tenga tiempo trataré de responderte. saludos!
حذفHola, muy buena información, de hecho está muy completa.
ردحذفMe gustaría saber como implementar un WebService con el google Maps para colocar el mapa de google en una ventana en jframe o frame y que me permita escoger un punto A y un punto B para saber las distancias y todo eso.
Si me puedes ayudar te agradecería porque estuve buscando por la red y no encontré algo específico.
Buenas, una información maravillosa, me sirvió mucho, me gustaría saber si en el lado del cliente en vez de utilizar una página de html usamos un cliente movil, con androdi por ejemplo, el rest necesitaría cambios o los cambios solo se realizarían en la zona del cliente.
ردحذفUn saludo gracias.
Hola +Joselu
حذفLa respuesta puede ser con xml o json. Para moviles es muy recomendable usar json ya que es simple y más ligero. Solo necesitas interpretar las respuestas usando bibliotecas como el GSon de Google para volverlas en objetos.