{"id":15541,"date":"2020-10-28T03:01:34","date_gmt":"2020-10-28T02:01:34","guid":{"rendered":"http:\/\/blog.wenzlaff.de\/?p=15541"},"modified":"2020-10-28T12:53:23","modified_gmt":"2020-10-28T11:53:23","slug":"rest-service-in-15-min-mit-quarkus-openapi-swagger-ui-und-junit-test-erstellen-und-um-co2-ampel-service-erweitern","status":"publish","type":"post","link":"http:\/\/blog.wenzlaff.de\/?p=15541","title":{"rendered":"REST Service in 15 min mit Quarkus, OpenAPI, Swagger UI und JUnit-Test erstellen und um CO2-Ampel Service erweitern"},"content":{"rendered":"<p>Einen REST Service in 15 min mit Quarkus, OpenAPI, Swagger UI und JUnit-Test erstellen und um CO2-Ampel Service erweitern ist nicht kompliziert.<br \/>\n<figure id=\"attachment_13737\" aria-describedby=\"caption-attachment-13737\" style=\"width: 5500px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2019\/10\/Quarks-rest-Java.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2019\/10\/Quarks-rest-Java.png\" alt=\"\" width=\"5500\" height=\"4000\" class=\"size-full wp-image-13737\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2019\/10\/Quarks-rest-Java.png 5500w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2019\/10\/Quarks-rest-Java-300x218.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2019\/10\/Quarks-rest-Java-768x559.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2019\/10\/Quarks-rest-Java-1024x745.png 1024w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><figcaption id=\"caption-attachment-13737\" class=\"wp-caption-text\">Freut euch immer<\/figcaption><\/figure><br \/>\nVorraussetzungen Java 11 und Maven. Test mit:<\/p>\n<p><strong>mvn -version<\/strong><\/p>\n<p>auf der Kommandozeile:<\/p>\n<pre class=\"lang:default decode:true \" >\u279c  ~ mvn -version\r\nApache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)\r\nMaven home: \/opt\/local\/share\/java\/maven3\r\nJava version: 11.0.9, vendor: AdoptOpenJDK, runtime: \/Library\/Java\/JavaVirtualMachines\/adoptopenjdk-11.jdk\/Contents\/Home\r\nDefault locale: de_DE, platform encoding: UTF-8\r\nOS name: \"mac os x\", version: \"10.15.7\", arch: \"x86_64\", family: \"mac\"<\/pre>\n<p>Dann fangen wir in einem leeren Verzeichnis an<\/p>\n<pre class=\"lang:default decode:true \" >mkdir rest-co2ampel\r\ncd rest-co2ampel<\/pre>\n<p>jetzt rufen wir mit dem Maven Quarkus Plugin das create Goal auf:<\/p>\n<pre class=\"lang:default decode:true \" >mvn io.quarkus:quarkus-maven-plugin:1.9.0.Final:create -DprojectGroupId=de.wenzlaff.co2ampel -DprojectArtifactId=info-kleinhirn -DclassName=\"de.wenzlaff.Co2AmpelResource\" -Dpath=\"\/co2ampel\"<\/pre>\n<p>Zwei Sekunden sp\u00e4ter, ist das Projekt angelegt:<!--more--><\/p>\n<pre class=\"lang:default decode:true \" >\r\n[INFO] ========================================================================================\r\n[INFO] Your new application has been created in \/Users\/thomaswenzlaff\/rest-co2ampel\/info-kleinhirn\r\n[INFO] Navigate into this directory and launch your application with mvn quarkus:dev\r\n[INFO] Your application will be accessible on http:\/\/localhost:8080\r\n[INFO] ========================================================================================\r\n[INFO]\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] BUILD SUCCESS\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] Total time:  1.898 s\r\n[INFO] Finished at: 2020-10-27T12:57:17+01:00\r\n[INFO] ------------------------------------------------------------------------\r\n<\/pre>\n<p>Nun gehen wir in das erzeugte Verzeichnis: <strong>cd info-kleinhirn<\/strong><\/p>\n<p>Nun starten wir den build und den Server mit:<\/p>\n<p><strong>mvn quarkus:dev<\/strong><\/p>\n<p>Ein paar Sekunden sp\u00e4ter ist alles gebaut, und der Server l\u00e4uft:<\/p>\n<pre class=\"lang:default decode:true \" >\r\n[INFO] Compiling 1 source file to \/Users\/thomaswenzlaff\/rest-co2ampel\/info-kleinhirn\/target\/classes\r\nListening for transport dt_socket at address: 5005\r\n__  ____  __  _____   ___  __ ____  ______\r\n --\/ __ \\\/ \/ \/ \/ _ | \/ _ \\\/ \/\/_\/ \/ \/ \/ __\/\r\n -\/ \/_\/ \/ \/_\/ \/ __ |\/ , _\/ ,< \/ \/_\/ \/\\ \\\r\n--\\___\\_\\____\/_\/ |_\/_\/|_\/_\/|_|\\____\/___\/\r\n2020-10-27 13:00:57,115 INFO  [io.quarkus] (Quarkus Main Thread) info-kleinhirn 1.0-SNAPSHOT on JVM (powered by Quarkus 1.9.0.Final) started in 0.836s. Listening on: http:\/\/0.0.0.0:8080\r\n2020-10-27 13:00:57,118 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.\r\n2020-10-27 13:00:57,118 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy]\r\n<\/pre>\n<p>Ein Aufruf von <\/p>\n<p><a href=\"http:\/\/localhost:8080\/\" rel=\"noopener noreferrer\" target=\"_blank\">http:\/\/localhost:8080\/<\/a> <\/p>\n<p>bringt die statische Webseite. Und ein <\/p>\n<p><a href=\"http:\/\/localhost:8080\/co2ampel\" rel=\"noopener noreferrer\" target=\"_blank\">http:\/\/localhost:8080\/co2ampel<\/a><\/p>\n<p>liefert den Aufruf des REST CO2Ampel Services.<\/p>\n<p>Nun unterbrechen wir den Server mit CTLR-C und erg\u00e4nzen f\u00fcr den Test die Swaggert GUI hinzu, einfach ein<\/p>\n<pre class=\"lang:default decode:true \" >.\/mvnw quarkus:add-extension -Dextensions=\"quarkus-smallrye-openapi\"<\/pre>\n<p>und ein neues starten:<\/p>\n<p><strong>.\/mvnw compile quarkus:dev<\/strong><\/p>\n<p>Dann im Browser die GUI Aufrufen:<\/p>\n<p><a href=\"http:\/\/localhost:8080\/swagger-ui\/\" rel=\"noopener noreferrer\" target=\"_blank\">http:\/\/localhost:8080\/swagger-ui\/<\/a><\/p>\n<p>Cool:<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.10.44.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.10.44.png\" alt=\"\" width=\"2942\" height=\"1740\" class=\"aligncenter size-full wp-image-15543\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.10.44.png 2942w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.10.44-300x177.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.10.44-1024x606.png 1024w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.10.44-768x454.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.10.44-1536x908.png 1536w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.10.44-2048x1211.png 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>Und openapi geht auch, einfach in einem neuen Fenster ein <\/p>\n<p><strong>curl http:\/\/localhost:8080\/openapi <\/strong><\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.13.10.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.13.10.png\" alt=\"\" width=\"912\" height=\"822\" class=\"aligncenter size-full wp-image-15544\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.13.10.png 912w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.13.10-300x270.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-13.13.10-768x692.png 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>So, jetzt nur noch echt CO2 Messung einbauen. Ich habe einen Mqtt-Broker der die Werte liefert.<\/p>\n<p>Wir gehen in das Verzeichnis und <strong>\/rest-co2ampel\/info-kleinhirn\/src\/main\/java\/de\/wenzlaff<\/strong> und holen uns die zwei Beispielklasse von github mit:<\/p>\n<pre class=\"lang:default decode:true \" >\r\ncurl https:\/\/gist.githubusercontent.com\/IT-Berater\/c58da54b1f20337827f8de827715d728\/raw\/10d721ca73148b3be195d6fc2fa45ff02af42d9d\/CO2AmpelResource.java &gt; CO2AmpelResource.java\r\n\r\ncurl https:\/\/gist.githubusercontent.com\/IT-Berater\/dc7695fdb406d6f93d4a47553d309ec9\/raw\/a7928a1527d164d2a51ddece19fefc431c3c46a1\/MqttCo2Client.java &gt; MqttCo2Client.java<\/pre>\n<p>Dann gehen wir in das Wurzelverzeichnis des Projektes und f\u00fcgen in der <strong>pom.xml<\/strong> diese beiden abh\u00e4ngigkeiten hinzu:<\/p>\n<pre class=\"lang:xhtml decode:true \" >\r\n&lt;dependency&gt;\r\n   &lt;groupId&gt;org.eclipse.paho&lt;\/groupId&gt;\r\n   &lt;artifactId&gt;org.eclipse.paho.client.mqttv3&lt;\/artifactId&gt;\r\n   &lt;version&gt;1.2.5&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n&lt;dependency&gt;\r\n  &lt;groupId&gt;org.json&lt;\/groupId&gt;\r\n  &lt;artifactId&gt;json&lt;\/artifactId&gt;\r\n  &lt;version&gt;20200518&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n<\/pre>\n<p>Dann m\u00fcssen wir noch den JUnit Test anpassen.Dazu die Testklasse Co2AmpelResourceTest.java in der Methode testHelloEndpoint() diesen Inhalt einf\u00fcgen: <\/p>\n<pre class=\"lang:default decode:true \" >given().when().get(\"\/v1\/rest\/co2\").then().statusCode(200).body(is(\"CO2 Wert: 0\"));<\/pre>\n<p>So, nun k\u00f6nnen wir das Projekt starten:<\/p>\n<p><strong>.\/mvnw compile quarkus:dev <\/strong><\/p>\n<p>So der JUnit Test wurde erfolgreich ausgef\u00fchrt. Nun kann der REST-Service \u00fcber die URL<\/p>\n<p><a href=\"http:\/\/localhost:8080\/v1\/rest\/co2\" rel=\"noopener noreferrer\" target=\"_blank\">http:\/\/localhost:8080\/v1\/rest\/co2<\/a><\/p>\n<p>abgefragt werden. Wenn der Mqtt-Service Werte die entsprechenden Werte liefert, sonst 0 \ud83d\ude09<\/p>\n<p>Und auch \u00fcber die openapi stehen die REST-Services bereit, cool ...<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.55.34.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.55.34.png\" alt=\"\" width=\"2904\" height=\"1830\" class=\"aligncenter size-full wp-image-15547\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.55.34.png 2904w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.55.34-300x189.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.55.34-1024x645.png 1024w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.55.34-768x484.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.55.34-1536x968.png 1536w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.55.34-2048x1291.png 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.57.55.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.57.55.png\" alt=\"\" width=\"2826\" height=\"1564\" class=\"aligncenter size-full wp-image-15548\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.57.55.png 2826w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.57.55-300x166.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.57.55-1024x567.png 1024w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.57.55-768x425.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.57.55-1536x850.png 1536w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-18.57.55-2048x1133.png 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>Openapi geht auch:<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.05.34.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.05.34.png\" alt=\"\" width=\"824\" height=\"1276\" class=\"aligncenter size-full wp-image-15554\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.05.34.png 824w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.05.34-194x300.png 194w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.05.34-661x1024.png 661w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.05.34-768x1189.png 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>Und hier, wenn der Mqtt-Server echte Werte liefert (evl. den Server localhost in der Java-Klasse MqttCo2Client durch einen anderen ersetzen, bei mir l\u00e4uf der CO2-Sensor auf einem Raspberry Pi, wie hier im Blog beschrieben):<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.25.39.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.25.39.png\" alt=\"\" width=\"2680\" height=\"1586\" class=\"aligncenter size-full wp-image-15559\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.25.39.png 2680w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.25.39-300x178.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.25.39-1024x606.png 1024w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.25.39-768x454.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.25.39-1536x909.png 1536w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.25.39-2048x1212.png 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>So, jetzt muss ich aber l\u00fcften ...<a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.07.52.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.07.52.png\" alt=\"\" width=\"770\" height=\"862\" class=\"aligncenter size-full wp-image-15557\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.07.52.png 770w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.07.52-268x300.png 268w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2020\/10\/wenzlaff.de-2020-10-27-um-19.07.52-768x860.png 768w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>REST-Api mit Quarkus in 15 Minuten erstellen<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[220,4084,5,3423,808,3773,3163,79],"tags":[4108,4057,2178,4110,3764,2487,4109,4107,4106],"class_list":["post-15541","post","type-post","status-publish","format-standard","hentry","category-anleitung","category-co2","category-java","category-java-11","category-linux-2","category-mac-os","category-maven","category-programmierung","tag-co","tag-co2ampel","tag-java","tag-openapi","tag-quarkus","tag-rest","tag-rest-service","tag-swaggert","tag-swaggert-ui"],"_links":{"self":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/15541","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=15541"}],"version-history":[{"count":0,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/15541\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=15541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=15541"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=15541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}