¡JAX-RS es solo una API!

1. Información general

El paradigma REST ha existido durante bastantes años y todavía recibe mucha atención.

Una API RESTful se puede implementar en Java de varias maneras: puede usar Spring, JAX-RS, o simplemente puede escribir sus propios servlets si es lo suficientemente bueno y valiente. Todo lo que necesita es la capacidad de exponer métodos HTTP; el resto se trata de cómo los organiza y cómo guía al cliente cuando realiza llamadas a su API.

Como puede ver en el título, este artículo cubrirá JAX-RS. Pero, ¿qué significa "solo una API"? Significa que el enfoque aquí es aclarar la confusión entre JAX-RS y sus implementaciones y ofrecer un ejemplo de cómo se ve una aplicación web JAX-RS adecuada.

2. Inclusión en Java EE

JAX-RS no es más que una especificación, un conjunto de interfaces y anotaciones ofrecidas por Java EE. Y luego, por supuesto, tenemos las implementaciones; algunos de los más conocidos son RESTEasy y Jersey.

Además, si alguna vez decide construir un servidor de aplicaciones compatible con JEE, los chicos de Oracle le dirán que, entre muchas otras cosas, su servidor debe proporcionar una implementación JAX-RS para que la utilicen las aplicaciones implementadas. Por eso se llama Plataforma Java Enterprise Edition .

Otro buen ejemplo de especificación e implementación es JPA e Hibernate.

2.1. Guerras ligeras

Entonces, ¿cómo nos ayuda todo esto a los desarrolladores? La ayuda está en que nuestros implementables pueden y deben ser muy delgados, permitiendo que el servidor de aplicaciones proporcione las bibliotecas necesarias. Esto también se aplica cuando se desarrolla una API RESTful: el artefacto final no debe contener ninguna información sobre la implementación JAX-RS utilizada.

Claro, podemos proporcionar la implementación (aquí hay un tutorial para RESTeasy). Pero entonces ya no podemos llamar a nuestra aplicación "aplicación Java EE". Si mañana alguien viene y dice “ Ok, es hora de cambiar a Glassfish o Payara, ¡JBoss se volvió demasiado caro! “, Podríamos hacerlo, pero no será un trabajo fácil.

Si proporcionamos nuestra propia implementación, tenemos que asegurarnos de que el servidor sepa excluir la suya propia; esto suele suceder al tener un archivo XML propietario dentro del desplegable. No hace falta decir que dicho archivo debería contener todo tipo de etiquetas e instrucciones de las que nadie sabe nada, excepto los desarrolladores que dejaron la empresa hace tres años.

2.2. Conozca siempre su servidor

Hasta ahora dijimos que deberíamos aprovechar la plataforma que nos ofrecen.

Antes de decidir qué servidor utilizar, deberíamos ver qué implementación JAX-RS (nombre, proveedor, versión y errores conocidos) proporciona, al menos para entornos de producción. Por ejemplo, Glassfish viene con Jersey, mientras que Wildfly o Jboss vienen con RESTEasy.

Esto, por supuesto, significa un poco de tiempo dedicado a la investigación, pero se supone que debe hacerse solo una vez, al comienzo del proyecto o al migrarlo a otro servidor.

3. Un ejemplo

Si desea comenzar a jugar con JAX-RS, la ruta más corta es: tenga un proyecto de aplicación web Maven con la siguiente dependencia en pom.xml :

 javax javaee-api 7.0 provided  

Estamos usando JavaEE 7 porque ya hay muchos servidores de aplicaciones que lo implementan. Ese tarro de API contiene las anotaciones que necesita usar, ubicadas en el paquete javax.ws.rs . ¿Por qué se "proporciona" el alcance? Debido a que este jar tampoco necesita estar en la compilación final, lo necesitamos en tiempo de compilación y el servidor lo proporciona para el tiempo de ejecución.

Después de agregar la dependencia, primero tenemos que escribir la clase de entrada: una clase vacía que amplía javax.ws.rs.core.Application y se anota con javax.ws.rs.ApplicationPath:

@ApplicationPath("/api") public class RestApplication extends Application { } 

Definimos la ruta de entrada como / api. Cualesquiera otras rutas que declaremos para nuestros recursos, tendrán el prefijo / api .

A continuación, veamos un recurso:

@Path("/notifications") public class NotificationsResource { @GET @Path("/ping") public Response ping() { return Response.ok().entity("Service online").build(); } @GET @Path("/get/{id}") @Produces(MediaType.APPLICATION_JSON) public Response getNotification(@PathParam("id") int id) { return Response.ok() .entity(new Notification(id, "john", "test notification")) .build(); } @POST @Path("/post/") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Response postNotification(Notification notification) { return Response.status(201).entity(notification).build(); } }

Tenemos un punto final de ping simple para llamar y verificar si nuestra aplicación se está ejecutando, un GET y un POST para una notificación (esto es solo un POJO con atributos más getters y setters).

Implemente esta guerra en cualquier servidor de aplicaciones que implemente JEE7 y los siguientes comandos funcionarán:

curl //localhost:8080/simple-jaxrs-ex/api/notifications/ping/ curl //localhost:8080/simple-jaxrs-ex/api/notifications/get/1 curl -X POST -d '{"id":23,"text":"lorem ipsum","username":"johana"}' //localhost:8080/simple-jaxrs-ex/api/notifications/post/ --header "Content-Type:application/json"

Donde simple-jaxrs-ex es la raíz de contexto de la aplicación web.

Esto se probó con Glassfish 4.1.0 y Wildfly 9.0.1.Final. Tenga en cuenta que los dos últimos comandos no funcionarán con Glassfish 4.1.1, debido a este error. Aparentemente, es un problema conocido en esta versión de Glassfish, con respecto a la serialización de JSON (si tiene que usar esta versión de servidor, tendrá que administrar la clasificación de JSON por su cuenta)

4. Conclusión

Al final de este artículo, solo tenga en cuenta que JAX-RS es una API poderosa y la mayoría (si no todas) las cosas que necesita ya están implementadas por su servidor web. No es necesario convertir su despliegue en un montón de bibliotecas inmanejables.

Este artículo presenta un ejemplo simple y las cosas pueden complicarse más. Por ejemplo, es posible que desee escribir sus propios indicadores. Cuando sea necesario, busque tutoriales que resuelvan su problema con JAX-RS, no con Jersey, Resteasy u otra implementación concreta. Es muy probable que su problema pueda resolverse con una o dos anotaciones.