JAX-RS n'est qu'une API!

1. Vue d'ensemble

Le paradigme REST existe depuis plusieurs années maintenant et il retient toujours beaucoup l'attention.

Une API RESTful peut être implémentée en Java de plusieurs manières: vous pouvez utiliser Spring, JAX-RS, ou vous pouvez simplement écrire vos propres servlets simples si vous êtes assez bon et courageux. Tout ce dont vous avez besoin est la possibilité d'exposer les méthodes HTTP - le reste concerne la manière dont vous les organisez et comment vous guidez le client lors des appels à votre API.

Comme vous pouvez le voir dans le titre, cet article couvrira JAX-RS. Mais que signifie «juste une API»? Cela signifie que l'accent est mis ici sur la clarification de la confusion entre JAX-RS et ses implémentations et sur l'offre d'un exemple de ce à quoi ressemble une application Web JAX-RS appropriée.

2. Inclusion dans Java EE

JAX-RS n'est rien de plus qu'une spécification, un ensemble d'interfaces et d'annotations proposées par Java EE. Et puis, bien sûr, nous avons les implémentations; certains des plus connus sont RESTEasy et Jersey.

De plus, si vous décidez de créer un serveur d'applications compatible JEE, les responsables d'Oracle vous diront que, entre autres choses, votre serveur doit fournir une implémentation JAX-RS pour les applications déployées à utiliser. C'est pourquoi il s'appelle Java Enterprise Edition Platform .

Un autre bon exemple de spécification et d'implémentation est JPA et Hibernate.

2.1. Guerres légères

Alors, comment tout cela nous aide-t-il, les développeurs? L'aide réside dans le fait que nos déploiables peuvent et doivent être très minces, laissant le serveur d'applications fournir les bibliothèques nécessaires. Cela s'applique également lors du développement d'une API RESTful: l'artefact final ne doit contenir aucune information sur l'implémentation JAX-RS utilisée.

Bien sûr, nous pouvons fournir l'implémentation (voici un tutoriel pour RESTeasy). Mais alors nous ne pouvons plus appeler notre application «application Java EE». Si demain quelqu'un vient et dit « Ok, il est temps de passer à Glassfish ou Payara, JBoss est devenu trop cher! «, Nous pourrons peut-être le faire, mais ce ne sera pas une tâche facile.

Si nous fournissons notre propre implémentation, nous devons nous assurer que le serveur sait exclure la sienne - cela se produit généralement en ayant un fichier XML propriétaire dans le déployable. Inutile de dire qu'un tel fichier doit contenir toutes sortes de balises et d'instructions dont personne ne sait rien, à l'exception des développeurs qui ont quitté l'entreprise il y a trois ans.

2.2. Connaissez toujours votre serveur

Nous avons dit jusqu'à présent que nous devrions profiter de la plate-forme qui nous est proposée.

Avant de décider du serveur à utiliser, nous devrions voir quelle implémentation JAX-RS (nom, fournisseur, version et bogues connus) il fournit, au moins pour les environnements de production. Par exemple, Glassfish est livré avec Jersey, tandis que Wildfly ou Jboss sont livrés avec RESTEasy.

Cela, bien sûr, signifie un peu de temps consacré à la recherche, mais c'est censé être fait une seule fois, au début du projet ou lors de sa migration vers un autre serveur.

3. Un exemple

Si vous voulez commencer à jouer avec JAX-RS, le chemin le plus court est: avoir un projet webapp Maven avec la dépendance suivante dans le pom.xml :

 javax javaee-api 7.0 provided  

Nous utilisons JavaEE 7 car il existe déjà de nombreux serveurs d'applications qui l'implémentent. Ce fichier API contient les annotations que vous devez utiliser, situées dans le package javax.ws.rs . Pourquoi la portée est-elle «fournie»? Parce que ce fichier jar n'a pas besoin non plus d'être dans la version finale - nous en avons besoin au moment de la compilation et il est fourni par le serveur pour l'exécution.

Une fois la dépendance ajoutée, nous devons d'abord écrire la classe d'entrée: une classe vide qui étend javax.ws.rs.core.Application et est annotée avec javax.ws.rs.ApplicationPath:

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

Nous avons défini le chemin d'entrée comme étant / api. Quels que soient les autres chemins que nous déclarons pour nos ressources, ils seront préfixés par / api .

Ensuite, voyons une ressource:

@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(); } }

Nous avons un simple point de terminaison ping à appeler et vérifier si notre application est en cours d'exécution, un GET et un POST pour une notification (il ne s'agit que d'un POJO avec des attributs plus des getters et des setters).

Déployez cette guerre sur n'importe quel serveur d'applications implémentant JEE7 et les commandes suivantes fonctionneront:

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"

Où simple-jaxrs-ex est la racine de contexte de l'application web.

Cela a été testé avec Glassfish 4.1.0 et Wildfly 9.0.1.Final. Veuillez noter que les deux dernières commandes ne fonctionneront pas avec Glassfish 4.1.1, à cause de ce bogue. C'est apparemment un problème connu dans cette version de Glassfish, concernant la sérialisation de JSON (si vous devez utiliser cette version de serveur, vous devrez gérer vous-même le marshaling JSON)

4. Conclusion

À la fin de cet article, gardez simplement à l'esprit que JAX-RS est une API puissante et que la plupart (sinon la totalité) des éléments dont vous avez besoin sont déjà implémentés par votre serveur Web. Pas besoin de transformer votre déployable en une pile de bibliothèques ingérable.

Cet article présente un exemple simple et les choses pourraient devenir plus compliquées. Par exemple, vous voudrez peut-être écrire vos propres marshalers. Lorsque cela est nécessaire, recherchez des tutoriels qui résolvent votre problème avec JAX-RS, pas avec Jersey, Resteasy ou toute autre implémentation concrète. Il est très probable que votre problème puisse être résolu avec une ou deux annotations.