JAX-RS ist nur eine API!

1. Übersicht

Das REST-Paradigma gibt es schon seit einigen Jahren und es wird immer noch viel beachtet.

Eine RESTful-API kann auf verschiedene Arten in Java implementiert werden: Sie können Spring, JAX-RS verwenden oder einfach Ihre eigenen nackten Servlets schreiben, wenn Sie gut und mutig genug sind. Alles, was Sie benötigen, ist die Möglichkeit, HTTP-Methoden verfügbar zu machen. Im Rest geht es darum, wie Sie sie organisieren und wie Sie den Client beim Aufrufen Ihrer API führen.

Wie Sie dem Titel entnehmen können, behandelt dieser Artikel JAX-RS. Aber was bedeutet "nur eine API"? Dies bedeutet, dass der Schwerpunkt hier darauf liegt, die Verwechslung zwischen JAX-RS und seinen Implementierungen zu klären und ein Beispiel dafür zu geben, wie eine richtige JAX-RS-Webanwendung aussieht.

2. Aufnahme in Java EE

JAX-RS ist nichts anderes als eine Spezifikation, eine Reihe von Schnittstellen und Anmerkungen, die von Java EE angeboten werden. Und dann haben wir natürlich die Implementierungen; Einige der bekanntesten sind RESTEasy und Jersey.

Wenn Sie sich jemals für die Erstellung eines JEE-kompatiblen Anwendungsservers entscheiden, werden Ihnen die Mitarbeiter von Oracle mitteilen, dass Ihr Server unter anderem eine JAX-RS-Implementierung für die bereitgestellten Apps bereitstellen sollte. Aus diesem Grund heißt es Java Enterprise Edition Platform .

Ein weiteres gutes Beispiel für Spezifikation und Implementierung ist JPA und Hibernate.

2.1. Leichte Kriege

Wie hilft uns das alles, den Entwicklern? Die Hilfe besteht darin, dass unsere Deployables sehr dünn sein können und sollten, sodass der Anwendungsserver die erforderlichen Bibliotheken bereitstellen kann. Dies gilt auch für die Entwicklung einer RESTful-API: Das endgültige Artefakt sollte keine Informationen über die verwendete JAX-RS-Implementierung enthalten.

Natürlich können wir die Implementierung bereitstellen (hier ist ein Tutorial für RESTeasy). Aber dann können wir unsere Anwendung nicht mehr "Java EE App" nennen. Wenn morgen jemand kommt und sagt: „ Ok, Zeit für einen Wechsel zu Glassfish oder Payara, JBoss wurde zu teuer! „Wir könnten es schaffen, aber es wird keine leichte Aufgabe.

Wenn wir unsere eigene Implementierung bereitstellen, müssen wir sicherstellen, dass der Server seine eigene ausschließen kann. Dies geschieht normalerweise, indem eine proprietäre XML-Datei im Deployable vorhanden ist. Natürlich sollte eine solche Datei alle Arten von Tags und Anweisungen enthalten, von denen niemand etwas weiß, außer den Entwicklern, die das Unternehmen vor drei Jahren verlassen haben.

2.2. Kennen Sie immer Ihren Server

Wir haben bisher gesagt, dass wir die angebotene Plattform nutzen sollten.

Bevor wir uns für einen Server entscheiden, sollten wir prüfen, welche JAX-RS-Implementierung (Name, Hersteller, Version und bekannte Fehler) zumindest für Produktionsumgebungen bereitgestellt wird. Zum Beispiel kommt Glassfish mit Jersey, während Wildfly oder Jboss mit RESTEasy kommen.

Dies bedeutet natürlich ein wenig Zeit für die Recherche, sollte jedoch nur einmal durchgeführt werden, zu Beginn des Projekts oder bei der Migration auf einen anderen Server.

3. Ein Beispiel

Wenn Sie mit JAX-RS spielen möchten, ist der kürzeste Weg: Haben Sie ein Maven-Webapp-Projekt mit der folgenden Abhängigkeit in der Datei pom.xml :

 javax javaee-api 7.0 provided  

Wir verwenden JavaEE 7, da es bereits viele Anwendungsserver gibt, die es implementieren. Diese API-JAR enthält die Anmerkungen, die Sie verwenden müssen, im Paket javax.ws.rs . Warum ist der Umfang "vorgesehen"? Da dieses JAR auch nicht im endgültigen Build enthalten sein muss, benötigen wir es zur Kompilierungszeit und es wird vom Server für die Laufzeit bereitgestellt.

Nachdem die Abhängigkeit hinzugefügt wurde, müssen wir zuerst die Eintragsklasse schreiben: eine leere Klasse, die javax.ws.rs.core.Application erweitert und mit javax.ws.rs.ApplicationPath kommentiert wird:

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

Wir haben den Einstiegspfad als / api definiert. Unabhängig davon, welche anderen Pfade wir für unsere Ressourcen deklarieren, wird ihnen / api vorangestellt .

Als nächstes sehen wir uns eine Ressource an:

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

Wir haben einen einfachen Ping-Endpunkt zum Aufrufen und Überprüfen, ob unsere App ausgeführt wird, einen GET und einen POST für eine Benachrichtigung (dies ist nur ein POJO mit Attributen plus Getter und Setter).

Stellen Sie diesen Krieg auf jedem Anwendungsserver bereit, der JEE7 implementiert, und die folgenden Befehle funktionieren:

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"

Wobei simple-jaxrs-ex die Kontextwurzel der Webanwendung ist.

Dies wurde mit Glassfish 4.1.0 und Wildfly 9.0.1.Final getestet. Bitte beachten Sie, dass die letzten beiden Befehle aufgrund dieses Fehlers nicht mit Glassfish 4.1.1 funktionieren. Es ist anscheinend ein bekanntes Problem in dieser Glassfish-Version in Bezug auf die Serialisierung von JSON (wenn Sie diese Serverversion verwenden müssen, müssen Sie das JSON-Marshalling selbst verwalten).

4. Fazit

Denken Sie am Ende dieses Artikels daran, dass JAX-RS eine leistungsstarke API ist und die meisten (wenn nicht alle) Dinge, die Sie benötigen, bereits von Ihrem Webserver implementiert sind. Sie müssen Ihr Deployable nicht in einen nicht verwaltbaren Stapel von Bibliotheken verwandeln.

Diese Beschreibung stellt ein einfaches Beispiel dar und die Dinge könnten komplizierter werden. Zum Beispiel möchten Sie vielleicht Ihre eigenen Marschälle schreiben. Suchen Sie bei Bedarf nach Tutorials, die Ihr Problem mit JAX-RS lösen, nicht mit Jersey, Resteasy oder einer anderen konkreten Implementierung. Es ist sehr wahrscheinlich, dass Ihr Problem mit ein oder zwei Anmerkungen gelöst werden kann.