{"id":19047,"date":"2020-08-17T08:39:54","date_gmt":"2020-08-17T06:39:54","guid":{"rendered":"https:\/\/www.inovex.de\/blog\/?p=19047"},"modified":"2023-11-27T09:20:52","modified_gmt":"2023-11-27T08:20:52","slug":"backend-tech-stacks-java-kotlin","status":"publish","type":"post","link":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/","title":{"rendered":"Backend Tech Stacks: Java und Kotlin"},"content":{"rendered":"<p>In dieser Artikelserie m\u00f6chten wir euch einen Einblick geben, wie typische Projekte aus technologischer Sicht bei uns aussehen. Wir betrachten dazu in einzelnen kurzen Artikeln unterschiedliche Tech Stacks.<\/p>\n<p>Wir ber\u00fccksichtigen dabei auf keinen Fall all unsere Projekte, m\u00f6chten aber zeigen, wie viele Projekte in diesem Bereich aufgebaut sind. Es geht uns hier also weniger um die Bandbreite aller Projekte, sondern eher h\u00e4ufig auftretende Gemeinsamkeiten.<\/p>\n<p>In diesem Artikel behandeln wir die Projekte mit Java- und\/oder Kotlin-Backend. Im \u00fcbrigen: Wenn euch ein Thema\/Tool\/Bibliothek n\u00e4her interessiert und wir z.B. einen Artikel zu Tipps, Tricks und Fallstricke dazu erstellen sollen, hinterlasst gerne einen Kommentar.<\/p>\n<p><!--more--><\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_83 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\"><\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Basistechnologie\" >Basistechnologie<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Libraries-und-Third-Party-Erweiterungen\" >Libraries und Third-Party-Erweiterungen<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Das-Oekosystem\" >Das \u00d6kosystem<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#ORM\" >ORM<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#HTTP-API-De-Serialisierung-Dokumentation\" >HTTP API, De-\/Serialisierung, Dokumentation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Monitoring\" >Monitoring<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Logging\" >Logging<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Kleine-Helferlein\" >Kleine Helferlein<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Testing\" >Testing<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Tooling\" >Tooling<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Hosting-und-Operations\" >Hosting und Operations<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Public-Cloud\" >Public Cloud<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#CICD\" >CI\/CD<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#Zusammenfassung\" >Zusammenfassung<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Basistechnologie\"><\/span>Basistechnologie<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Bis vor ein paar Jahren sahen viele Java-Backend-Projekte, die bei uns auf der gr\u00fcnen Wiese gestartet sind, sehr \u00e4hnlich aus: Spring (Boot), JPA, REST API, &#8230; Die letzten Jahre haben aber f\u00fcr neuen Schwung gesorgt. Durch neue Sprachen wie Kotlin oder die gewachsenen Anforderungen einer Microservice-Landschaft sind neue Technologien entstanden (Micronaut, Quarkus, \u2026).<\/p>\n<p>Deshalb m\u00fcssen wir, um den typischen Tech-Stack von Java-Backend-Projekten bei uns vorzustellen, hier und da etwas differenzieren.<\/p>\n<p>Die Basis stellt Java 11-14 dar. Je Nach Entwicklerpr\u00e4ferenz wird zunehmend Kotlin verwendet. Da als Hauptbestandteil weiterhin Spring (Boot) zum Einsatz kommt, wollen wir uns in diesem Artikel auf dieses fokussieren.<\/p>\n<p><strong><a href=\"https:\/\/spring.io\/\">Spring<\/a><\/strong> ist eines von vielen Java (und Kotlin) Frameworks da drau\u00dfen, geh\u00f6rt aber sicher zu den bekannteren Vertretern. Es unterst\u00fctzt dabei, einfache Web-APIs und andere Anwendungen <em>produktionsreif<\/em> entwickeln zu k\u00f6nnen. Die Kernfunktionen beinhalten Dependency Injection und damit sogenannte Spring Beans. Der Lifecycle der meisten Funktionen muss also nicht selbst behandelt werden. Spring hilft simpel gesagt an den meisten Ecken der Service Entwicklung.<\/p>\n<p><a href=\"https:\/\/spring.io\/projects\/spring-boot\"><strong>Spring Boot<\/strong><\/a> ist mehr oder weniger die Basis aus der Werkzeugpalette im Spring-\u00d6kosystem. Es bringt zus\u00e4tzlich die Funktionalit\u00e4t, standalone Spring-Applikationen deployen zu k\u00f6nnen, sehr weitgehende automatisch konfigurierte Werte und Funktionen, wie Health Checks und Konfigurierbarkeit.<\/p>\n<p>Zu Spring Boot kommt in aller Regel dann noch Spring Security, was (wie der Name bereits verr\u00e4t) diverse Sicherheits-Features mitbringt und Funktionen wie Authentication und Authorization weitgehend frei ab Werk mitbringt.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Libraries-und-Third-Party-Erweiterungen\"><\/span>Libraries und Third-Party-Erweiterungen<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h3><span class=\"ez-toc-section\" id=\"Das-Oekosystem\"><\/span>Das \u00d6kosystem<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Um n\u00e4her auf die einzelnen Bestandteile eines exemplarischen Services einzugehen, werden wir im folgenden auf die Technologien und Bibliotheken eingehen, die man in fast jedem Service ben\u00f6tigt.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"ORM\"><\/span>ORM<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Sehr viele Dienste ben\u00f6tigen die Anbindung an eine relationale Datenbank. Das Spring-\u00d6kosystem bietet hierbei vielfach Unterst\u00fctzung, so dass man sich auf die Fachlichkeit konzentrieren kann.<\/p>\n<p>Zum Mapping zwischen Datenbank und Applikations-Code wird <strong>JPA mit <a href=\"https:\/\/hibernate.org\/orm\/\">Hibernate <\/a><\/strong>verwendet. Hierbei reicht in den meisten F\u00e4llen der Funktionsumfang des JPA 2.1\/2.2 Standard. Alternativ bietet Hibernate wie auch andere ORM-Anbieter aber teilweise sehr n\u00fctzliche Erweiterungen (<code><a href=\"https:\/\/docs.jboss.org\/hibernate\/orm\/current\/javadocs\/org\/hibernate\/annotations\/BatchSize.html\">@BatchSize<\/a><\/code>, <code><a href=\"https:\/\/docs.jboss.org\/hibernate\/orm\/6.0\/javadocs\/org\/hibernate\/annotations\/Where.html\">@Where<\/a><\/code>, <code><a href=\"https:\/\/docs.jboss.org\/hibernate\/orm\/5.3\/javadocs\/index.html?org\/hibernate\/annotations\/NotFound.html\">@NotFound<\/a><\/code>, &#8230;)<\/p>\n<p>Zur Kommunikation mit der DB wird mit <strong><a href=\"https:\/\/spring.io\/projects\/spring-data-jpa\">Spring Data JPA<\/a><\/strong> noch ein weiteres Abstraktionslevel verwendet, wodurch die Abfragen sich sehr einfach in den bisherigen Code integrieren. Falls die Performance ein wichtiger Faktor ist, wird auf die Criteria API gewechselt. Ben\u00f6tigt man viele Kombinationen von vorhandenen Methoden wie z.B. zur selektiven Anwendung verschiedener Filter k\u00f6nnen <a href=\"https:\/\/docs.spring.io\/spring-data\/jpa\/reference\/jpa\/specifications.html\">Specifications<\/a> den Code les- und wartbarer machen.<\/p>\n<p>Wie man schon herauslesen kann, wird das DB-Schema hierbei durch den Code-First Ansatz erstellt. Au\u00dferdem gehen wir iterativ vor, so dass \u00c4nderungen fast allt\u00e4glich sind. Um hierbei den \u00dcberblick zu behalten, welcher Stand des DB-Schemas aktuell ist und was zu tun ist, um einen gewissen Stand zu erreichen, werden Schema-Versionierungs-Tools wie <strong><a href=\"https:\/\/flywaydb.org\/\">Flyway<\/a> oder <a href=\"https:\/\/www.liquibase.org\/\">Liquibase<\/a> <\/strong>eingesetzt. Zudem wird damit jede \u00c4nderung am Schema automatisch verst\u00e4ndlich dokumentiert und neben dem Code im SCM Tool abgelegt.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"HTTP-API-De-Serialisierung-Dokumentation\"><\/span>HTTP API, De-\/Serialisierung, Dokumentation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Zu jedem Restful Webservice geh\u00f6rt eine anst\u00e4ndige HTTP API. <strong>Spring WebMVC<\/strong>\u00a0deckt einige der typischen Anwendungsf\u00e4lle ab:<\/p>\n<ul>\n<li>Content Negotiation: Wir verwenden ContentType- und Accept-Header hierbei auch gerne zur Versionierung der API<\/li>\n<li>De-\/Serialisierung bzw. automatische Konfiguration zu g\u00e4ngigen Mapping-Frameworks wie <a href=\"https:\/\/github.com\/FasterXML\/jackson\">Jackson Json<\/a>, <a href=\"https:\/\/github.com\/google\/gson\">Gson<\/a>, JAXB<\/li>\n<li>\u00dcbergreifende Fehlerbehandlung (<code>@ControllerAdvice<\/code>, <code>@ExceptionHandler<\/code>): Dadurch ist es m\u00f6glich, relativ einfach eine spezifische aber dennoch einheitliche Antwort zu generieren<\/li>\n<li>CORS: Mit wenig Konfiguration generiert die API dynamisch passende Antworten auf bei CORS relevante Anfragen<\/li>\n<li>Filter und Resource Handling: z.B. f\u00fcr statische Ressourcen, Querschnittsfunktionalit\u00e4ten, &#8230;<\/li>\n<\/ul>\n<p>Auch wenn nicht jede API \u00f6ffentlich von vielf\u00e4ltigen Clients verwendet wird, so ist mindestens eine einfache Dokumentation der REST-Schnittstelle sinnvoll. Mit <strong><a href=\"https:\/\/springfox.github.io\/springfox\/\">SpringFox<\/a><\/strong> kann hierbei auf die bereits existierenden Spring-WebMVC-Konfiguration per Annotation zur\u00fcckgegriffen werden. Darauf aufbauend wird eine Swagger-JSON-Konfiguration generiert, die mit dem Swagger UI als Online-Dokumentation angeboten werden kann. Zudem kann man mit relativ wenig Aufwand die Funktionalit\u00e4t \u00fcber Plugins erweitern.\u00a0 Darin ist es z.B. m\u00f6glich, anhand weiterer Annotations wie @PreAuthorize oder andere Validierungs-Annotationen die Doku zu verbessern.<\/p>\n<p>Leider fehlt noch der <a href=\"https:\/\/github.com\/springfox\/springfox\/issues\/2022\">OpenAPI 3.0 Support<\/a>, der wichtige Verbesserungen u.a. im Bezug auf Polymorphie und der Verwendung von unterschiedlichen Content-Types am selben Endpunkt erlauben w\u00fcrde.<strong> <a href=\"https:\/\/springdoc.org\/\">SpringDoc<\/a> <\/strong>schlie\u00dft diese L\u00fccke, so dass man auf dieses Pferd setzen sollte, wenn der Support ben\u00f6tigt wird. <a href=\"https:\/\/github.com\/springfox\/springfox\/issues\/3337#issuecomment-648514145\">Ganz aktuell geht es aber auch bei SpringFox wieder voran<\/a> und die Version 3.0 soll auch dort in K\u00fcrze das lang ersehnte Feature liefern.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Monitoring\"><\/span>Monitoring<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Ein wichtiger Teil der\u00a0<em>production-ready<\/em> Features von Spring Boot sind Dinge rund um den Betrieb einer Anwendung, also Monitoring, Alarming, Health-Checks u.\u00e4.<\/p>\n<p>Die zugeh\u00f6rige API wird unter dem Modul <strong><a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/current\/reference\/html\/production-ready-features.html\">Actuator<\/a><\/strong>\u00a0zusammengefasst. Des weiteren stellt das Modul bereits einige fertige Health-Checks zur Verf\u00fcgung, die automatisch aktiviert werden, sobald der entsprechende Dienst bzw. die entsprechende Bibliothek verwendet wird (z.B. db, elasticsearch, smtp, \u2026).<\/p>\n<p>Diese Health-Checks f\u00fchrt das Actuator-Modul normalerweise synchron beim Aufruf vom \/actuator\/health-Endpunkt sequentiell aus. F\u00fcr einen LoadBalancer-Check ben\u00f6tigt man jedoch einen Health-Check, der schnell antwortet. Deshalb haben wir viele Checks auf asynchrone Ausf\u00fchrung umgestellt. Weiterhin bedeutet nicht jeder negative Check zwingend auch den Gesamtausfall eines Services und damit die Deaktivierung im LB. Je nach Anwendungsfall mussten wir deshalb zudem die Ergebnis-Status-Codes anpassen.<\/p>\n<p>F\u00fcr das Monitoring der Anwendung wurde das Projekt <a href=\"https:\/\/micrometer.io\/\">micrometer<\/a> im Rahmen von Spring Boot 2 ausgelagert. Dieses \u00fcbernimmt zum einen die Definition einer einheitlichen Schnittstelle und zum anderen die <em>\u00dcbersetzung<\/em> in die typischen Weiterverarbeiter solcher Informationen (prometheus, graphite, statsd, u.v.m).<\/p>\n<p>Bei der Verarbeitung von Fehlern kann <strong><a href=\"https:\/\/sentry.io\/welcome\/\">sentry<\/a><\/strong> sehr hilfreich sein. Man hat hier sowohl die M\u00f6glichkeit, die fertige kostenpflichtige SaaS oder aber eine self-hosted-Variante zu nutzen. Damit ist es sehr einfach, die Fehler von jedem Client und allen Backends zu sammeln und einen schnellen \u00dcberblick \u00fcber neue Fehler und deren H\u00e4ufigkeit zu bekommen. Die vorhandenen Client-SDKs sammeln viele Informationen automatisch ein, so dass die Integration nur wenige Zeilen Code und Konfiguration ben\u00f6tigt.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Logging\"><\/span>Logging<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Beim Logging setzen wir auf <strong><a href=\"http:\/\/logback.qos.ch\/\">Logback<\/a><\/strong> und die dazugeh\u00f6rige <a href=\"https:\/\/docs.spring.io\/spring-boot\/docs\/1.5.x\/reference\/html\/howto-logging.html\">Integration<\/a> von Spring Boot. Diese bietet zus\u00e4tzlich die M\u00f6glichkeit, eine Spring-profilspezifische Konfiguration zu erstellen. Des weiteren hilft die <a href=\"http:\/\/logback.qos.ch\/manual\/appenders.html#SizeAndTimeBasedRollingPolicy\">SizeAndTimeBasedRollingPolicy<\/a> von Logback dabei, die Platte mit Logs nicht zu \u00fcberf\u00fcllen, da automatisch Gr\u00f6\u00dfenverbrauchgrenzwerte eingehalten und \u00e4ltere Dateien aufger\u00e4umt werden.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Kleine-Helferlein\"><\/span>Kleine Helferlein<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Neben den gr\u00f6\u00dferen genannten Vertretern kommen auch kleinere Helfer zum Einsatz, die den Alltag nicht weniger verbessern.<\/p>\n<p><a href=\"https:\/\/projectlombok.org\/\"><strong>Lombok<\/strong><\/a> ist eine Library, die uns bei Verwendung von Java unterst\u00fctzt, m\u00f6glichst wenig <em>Boilerplate<\/em> selbst schreiben zu m\u00fcssen, da sie diese stattdessen einfach generiert. \u00dcber <em>annotations<\/em> k\u00f6nnen viele Standardfunktionen, wie Getter und Setter erzeugt oder auch das NULL-Handling vereinfacht werden. Nichtsdestotrotz kann es nach einer Umstellung zu Lombok zu <a href=\"https:\/\/github.com\/rzwitserloot\/lombok\/issues\/2149\">unerwartetem Verhalten<\/a> kommen. Auch sollte man sich z.B. weiterhin Gedanken machen, wie eine korrekte Hashcode\/Equals-Implementierung aussieht.<\/p>\n<p><a href=\"https:\/\/mapstruct.org\/\"><strong>mapstruct<\/strong><\/a> vereinfacht das Umwandeln zwischen unterschiedlichen Typen. Die Library kommt bei uns vor allem dann zum Einsatz, wenn Entity-Klassen in DTO-Klassen gemappt werden sollen. Zudem bietet es sehr viel Flexibilit\u00e4t und Sonderf\u00e4lle k\u00f6nnen mit Bordmitteln einfach umgesetzt werden.<\/p>\n<p><a href=\"https:\/\/github.com\/google\/guava\"><strong>Guava<\/strong><\/a> ist eine ganze Sammlung von Libraries, die von Google ver\u00f6ffentlicht wurden. Sie enthalten unterschiedliche n\u00fctzliche Collection Types und auch mathematische Funktionen, die im JDK nicht enthalten sind.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Testing\"><\/span>Testing<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Testing ist beim Code-Schreiben nicht weniger wichtig als der Anwendungscode und auch hierf\u00fcr gibt es Unterst\u00fctzung durch verschiedene Libraries. Das Testing-Framework der Wahl f\u00fcr uns ist dabei meist <a href=\"https:\/\/junit.org\/junit5\/\">JUnit<\/a>.<\/p>\n<p>Tests lassen sich zudem besser lesbar halten durch den Einsatz von <strong><a href=\"https:\/\/assertj.github.io\/doc\/\">AssertJ<\/a><\/strong>, was viele Erweiterungen f\u00fcr Assertions auf unterschiedliche Typen liefert. Das erleichtert sowohl das Schreiben als auch das Lesen von Tests. Es erh\u00f6ht au\u00dferdem auch die Aussagekraft der meisten Fehlermeldungen.<\/p>\n<p><a href=\"https:\/\/site.mockito.org\/\"><strong>mockito<\/strong><\/a> erleichtert in Tests das Mocking von Objekten und Returnwerten aus Funktionen auf verschiedene Arten.<\/p>\n<p>In der Kotlin-Welt setzen wir vermehrt auf MockK. <strong><a href=\"https:\/\/github.com\/mockk\/mockk\">MockK<\/a><\/strong> ist auch ein Mocking Framework, das jedoch speziell f\u00fcr Kotlin entwickelt wurde. Dadurch hat es im Gegensatz zu Mockito eine DSL, die es erm\u00f6glicht, mit idiomatischem Kotlin Code Mocks zu definieren. In Verbindung mit Spring Boot hilft uns <a href=\"https:\/\/github.com\/Ninja-Squad\/springmockk\">SpringMockK<\/a>\u00a0auch Spring Beans einfach mit anderem Verhalten zu ersetzen (<code>@MockBean<\/code>\/<code>@SpyBean<\/code>).<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Tooling\"><\/span>Tooling<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Jetbrains ist auch im Java- und Kotlin-Bereich der Platzhirsch unter den verf\u00fcgbaren IDEs. <strong><a href=\"https:\/\/www.jetbrains.com\/idea\/\">IntelliJ IDEA<\/a><\/strong> war die erste IDE aus dem Hause Jetbrains und brachte zu Beginn Features, die andere IDEs nicht unterst\u00fctzten. Au\u00dferdem wurde Kotlin bei Jetbrains selbst entwickelt, was die Kotlin-Unterst\u00fctzung in dieser IDE zu einem fast schon selbstverst\u00e4ndlichen Feature macht.<\/p>\n<p>Sicherlich nach wie vor einer der Klassiker bei der Java-Entwicklung ist aber auch die <a href=\"https:\/\/www.eclipse.org\/eclipseide\/\">Eclipse IDE<\/a>. Im Spring-Kontext ist dabei auch vor allem <a href=\"https:\/\/spring.io\/tools\">Spring Tools for Eclipse<\/a> zu nennen. Dies ist im Wesentlichen eine Erweiterung f\u00fcr Eclipse, das die Entwicklung mit Spring Komponenten sehr einfach und angenehm macht. IDEA von Jetbrains steht dem aber in nichts nach.<\/p>\n<p>Der Code-Editor <a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code<\/a> ist nat\u00fcrlich nahezu allgegenw\u00e4rtig und kommt auch bei der Java- und Kotlin-Entwicklung hin und wieder zum Einsatz. In dieser Sparte ist er bei uns allerdings mehr Gast als erste Wahl f\u00fcr den l\u00e4ngeren Projekteinsatz.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Hosting-und-Operations\"><\/span>Hosting und Operations<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Das Hosting unserer Java- und Kotlin-Anwendungen l\u00e4uft in zwei unterschiedlichen Varianten. Die Umgebungen unterscheiden sich dabei jeweils sehr voneinander, weshalb wir an dieser Stelle auch keine weiteren Infrastrukturkomponenten auff\u00fchren.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Public-Cloud\"><\/span>Public Cloud<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Wenn wir von Java oder Kotlin Services in Kombination mit Hosting in der Public Cloud sprechen, setzen wir h\u00e4ufig auf <strong><a href=\"https:\/\/aws.amazon.com\/\">Amazon Web Services (AWS)<\/a><\/strong>. Hier werden selten VMs eingesetzt, sondern in aller Regel <strong><a href=\"https:\/\/aws.amazon.com\/ecs\/\">ECS<\/a><\/strong> (containerisierte Anwendungen) oder <strong><a href=\"https:\/\/aws.amazon.com\/lambda\/\">lambdas<\/a><\/strong> (Serverless-Anwendungen).<\/p>\n<p>Zunehmend werden auch Azure-Produkte in Java- und Kotlin-Projekten eingesetzt. Hierbei vor allem die <strong><a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/app-service\/\">App Services<\/a><\/strong> oder <strong><a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/functions\/\">Azure Functions<\/a><\/strong>.<\/p>\n<p>Neben diesen Varianten setzen wir auch h\u00e4ufig auf Kubernetes-Umgebungen \u2013 wenn m\u00f6glich in einer gemanagten Variante auf einem der vorgenannten Public Cloud Anbieter.<\/p>\n<h3><span class=\"ez-toc-section\" id=\"CICD\"><\/span>CI\/CD<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Vor dem Hosting in beliebiger Variante steht im Java-Umfeld meist unser <strong><a href=\"https:\/\/about.gitlab.com\/\">GitLab<\/a><\/strong> mit entsprechenden CI und CD Pipelines. Wenn das Projekt auf Azure aufbaut, kommt in aller Regel auch <strong><a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/devops\/\">Azure DevOps<\/a><\/strong> zum Einsatz.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Zusammenfassung\"><\/span><b>Zusammenfassung<\/b><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Die letzten Jahre gab es zwar Bewegung im Java-Backend-Umfeld, die gro\u00dfen Eckpfeiler (u.a. Spring Boot, Spring Data, Hibernate) sind aber stabil geblieben und werden unver\u00e4ndert in den aktuellen Versionen eingesetzt.<\/p>\n<p>Wir haben hier versuch,t euch einen \u00dcberblick \u00fcber die technischen Komponenten eines <em>typischen Projektes<\/em> bei uns im Haus zu geben. Dabei haben wir bewusst nicht jeden Aspekt beleuchtet \u2013 auch weil es vereinzelt keine typische Wahl gibt. Wir hoffen, wir konnten euch einen guten Einblick geben.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In dieser Artikelserie m\u00f6chten wir euch einen Einblick geben, wie typische Projekte aus technologischer Sicht bei uns aussehen. Wir betrachten dazu in einzelnen kurzen Artikeln unterschiedliche Tech Stacks. Wir ber\u00fccksichtigen dabei auf keinen Fall all unsere Projekte, m\u00f6chten aber zeigen, wie viele Projekte in diesem Bereich aufgebaut sind. Es geht uns hier also weniger um [&hellip;]<\/p>\n","protected":false},"author":138,"featured_media":19459,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"ep_exclude_from_search":false,"footnotes":""},"tags":[68],"service":[425],"coauthors":[{"id":138,"display_name":"Daniel Schreier","user_nicename":"dschreier"}],"class_list":["post-19047","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-backend","service-backend"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Backend Tech Stacks: Java und Kotlin - inovex GmbH<\/title>\n<meta name=\"description\" content=\"In dieser Artikelserie m\u00f6chten wir euch einen Einblick geben, wie typische Projekte aus technologischer Sicht bei uns aussehen. Wir betrachten dazu in einzelnen kurzen Artikeln unterschiedliche Tech Stacks. In diesem behandeln wir die Projekte mit Java und\/oder Kotlin Backend.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Backend Tech Stacks: Java und Kotlin - inovex GmbH\" \/>\n<meta property=\"og:description\" content=\"In dieser Artikelserie m\u00f6chten wir euch einen Einblick geben, wie typische Projekte aus technologischer Sicht bei uns aussehen. Wir betrachten dazu in einzelnen kurzen Artikeln unterschiedliche Tech Stacks. In diesem behandeln wir die Projekte mit Java und\/oder Kotlin Backend.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/\" \/>\n<meta property=\"og:site_name\" content=\"inovex GmbH\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/inovexde\" \/>\n<meta property=\"article:published_time\" content=\"2020-08-17T06:39:54+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-11-27T08:20:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2020\/08\/toolkit-java-kotlin.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Daniel Schreier\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.inovex.de\/wp-content\/uploads\/2020\/08\/toolkit-java-kotlin-1024x576.png\" \/>\n<meta name=\"twitter:creator\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:site\" content=\"@inovexgmbh\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Daniel Schreier\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"8\u00a0Minuten\" \/>\n\t<meta name=\"twitter:label3\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data3\" content=\"Daniel Schreier\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/\"},\"author\":{\"name\":\"Daniel Schreier\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#\\\/schema\\\/person\\\/3dcec5277d616c22a8bcd132e05266d5\"},\"headline\":\"Backend Tech Stacks: Java und Kotlin\",\"datePublished\":\"2020-08-17T06:39:54+00:00\",\"dateModified\":\"2023-11-27T08:20:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/\"},\"wordCount\":1853,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/toolkit-java-kotlin.png\",\"keywords\":[\"Backend\"],\"articleSection\":[\"Applications\",\"General\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/\",\"name\":\"Backend Tech Stacks: Java und Kotlin - inovex GmbH\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/toolkit-java-kotlin.png\",\"datePublished\":\"2020-08-17T06:39:54+00:00\",\"dateModified\":\"2023-11-27T08:20:52+00:00\",\"description\":\"In dieser Artikelserie m\u00f6chten wir euch einen Einblick geben, wie typische Projekte aus technologischer Sicht bei uns aussehen. Wir betrachten dazu in einzelnen kurzen Artikeln unterschiedliche Tech Stacks. In diesem behandeln wir die Projekte mit Java und\\\/oder Kotlin Backend.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/toolkit-java-kotlin.png\",\"contentUrl\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/toolkit-java-kotlin.png\",\"width\":1920,\"height\":1080,\"caption\":\"Ein Wekrzeugkasten mit Hammer, Zange und Schraubenzieher\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/backend-tech-stacks-java-kotlin\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Backend Tech Stacks: Java und Kotlin\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#website\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/\",\"name\":\"inovex GmbH\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#organization\",\"name\":\"inovex GmbH\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/inovex-logo-16-9-1.png\",\"contentUrl\":\"https:\\\/\\\/www.inovex.de\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/inovex-logo-16-9-1.png\",\"width\":1921,\"height\":1081,\"caption\":\"inovex GmbH\"},\"image\":{\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/inovexde\",\"https:\\\/\\\/x.com\\\/inovexgmbh\",\"https:\\\/\\\/www.instagram.com\\\/inovexlife\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/inovex\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UC7r66GT14hROB_RQsQBAQUQ\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/#\\\/schema\\\/person\\\/3dcec5277d616c22a8bcd132e05266d5\",\"name\":\"Daniel Schreier\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c528335d505d7f130b20e35aaf89128199bd030768fffdda98423a4ddc19877c?s=96&d=retro&r=ga11a42c606092f7ee403db62eade98be\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c528335d505d7f130b20e35aaf89128199bd030768fffdda98423a4ddc19877c?s=96&d=retro&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/c528335d505d7f130b20e35aaf89128199bd030768fffdda98423a4ddc19877c?s=96&d=retro&r=g\",\"caption\":\"Daniel Schreier\"},\"url\":\"https:\\\/\\\/www.inovex.de\\\/de\\\/blog\\\/author\\\/dschreier\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Backend Tech Stacks: Java und Kotlin - inovex GmbH","description":"In dieser Artikelserie m\u00f6chten wir euch einen Einblick geben, wie typische Projekte aus technologischer Sicht bei uns aussehen. Wir betrachten dazu in einzelnen kurzen Artikeln unterschiedliche Tech Stacks. In diesem behandeln wir die Projekte mit Java und\/oder Kotlin Backend.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/","og_locale":"de_DE","og_type":"article","og_title":"Backend Tech Stacks: Java und Kotlin - inovex GmbH","og_description":"In dieser Artikelserie m\u00f6chten wir euch einen Einblick geben, wie typische Projekte aus technologischer Sicht bei uns aussehen. Wir betrachten dazu in einzelnen kurzen Artikeln unterschiedliche Tech Stacks. In diesem behandeln wir die Projekte mit Java und\/oder Kotlin Backend.","og_url":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/","og_site_name":"inovex GmbH","article_publisher":"https:\/\/www.facebook.com\/inovexde","article_published_time":"2020-08-17T06:39:54+00:00","article_modified_time":"2023-11-27T08:20:52+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2020\/08\/toolkit-java-kotlin.png","type":"image\/png"}],"author":"Daniel Schreier","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.inovex.de\/wp-content\/uploads\/2020\/08\/toolkit-java-kotlin-1024x576.png","twitter_creator":"@inovexgmbh","twitter_site":"@inovexgmbh","twitter_misc":{"Verfasst von":"Daniel Schreier","Gesch\u00e4tzte Lesezeit":"8\u00a0Minuten","Written by":"Daniel Schreier"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#article","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/"},"author":{"name":"Daniel Schreier","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/3dcec5277d616c22a8bcd132e05266d5"},"headline":"Backend Tech Stacks: Java und Kotlin","datePublished":"2020-08-17T06:39:54+00:00","dateModified":"2023-11-27T08:20:52+00:00","mainEntityOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/"},"wordCount":1853,"commentCount":1,"publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2020\/08\/toolkit-java-kotlin.png","keywords":["Backend"],"articleSection":["Applications","General"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/","url":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/","name":"Backend Tech Stacks: Java und Kotlin - inovex GmbH","isPartOf":{"@id":"https:\/\/www.inovex.de\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#primaryimage"},"image":{"@id":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#primaryimage"},"thumbnailUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2020\/08\/toolkit-java-kotlin.png","datePublished":"2020-08-17T06:39:54+00:00","dateModified":"2023-11-27T08:20:52+00:00","description":"In dieser Artikelserie m\u00f6chten wir euch einen Einblick geben, wie typische Projekte aus technologischer Sicht bei uns aussehen. Wir betrachten dazu in einzelnen kurzen Artikeln unterschiedliche Tech Stacks. In diesem behandeln wir die Projekte mit Java und\/oder Kotlin Backend.","breadcrumb":{"@id":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#primaryimage","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2020\/08\/toolkit-java-kotlin.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2020\/08\/toolkit-java-kotlin.png","width":1920,"height":1080,"caption":"Ein Wekrzeugkasten mit Hammer, Zange und Schraubenzieher"},{"@type":"BreadcrumbList","@id":"https:\/\/www.inovex.de\/de\/blog\/backend-tech-stacks-java-kotlin\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.inovex.de\/de\/"},{"@type":"ListItem","position":2,"name":"Backend Tech Stacks: Java und Kotlin"}]},{"@type":"WebSite","@id":"https:\/\/www.inovex.de\/de\/#website","url":"https:\/\/www.inovex.de\/de\/","name":"inovex GmbH","description":"","publisher":{"@id":"https:\/\/www.inovex.de\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.inovex.de\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/www.inovex.de\/de\/#organization","name":"inovex GmbH","url":"https:\/\/www.inovex.de\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/","url":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","contentUrl":"https:\/\/www.inovex.de\/wp-content\/uploads\/2021\/03\/inovex-logo-16-9-1.png","width":1921,"height":1081,"caption":"inovex GmbH"},"image":{"@id":"https:\/\/www.inovex.de\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/inovexde","https:\/\/x.com\/inovexgmbh","https:\/\/www.instagram.com\/inovexlife\/","https:\/\/www.linkedin.com\/company\/inovex","https:\/\/www.youtube.com\/channel\/UC7r66GT14hROB_RQsQBAQUQ"]},{"@type":"Person","@id":"https:\/\/www.inovex.de\/de\/#\/schema\/person\/3dcec5277d616c22a8bcd132e05266d5","name":"Daniel Schreier","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/c528335d505d7f130b20e35aaf89128199bd030768fffdda98423a4ddc19877c?s=96&d=retro&r=ga11a42c606092f7ee403db62eade98be","url":"https:\/\/secure.gravatar.com\/avatar\/c528335d505d7f130b20e35aaf89128199bd030768fffdda98423a4ddc19877c?s=96&d=retro&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c528335d505d7f130b20e35aaf89128199bd030768fffdda98423a4ddc19877c?s=96&d=retro&r=g","caption":"Daniel Schreier"},"url":"https:\/\/www.inovex.de\/de\/blog\/author\/dschreier\/"}]}},"_links":{"self":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/19047","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/users\/138"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/comments?post=19047"}],"version-history":[{"count":5,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/19047\/revisions"}],"predecessor-version":[{"id":49910,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/posts\/19047\/revisions\/49910"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media\/19459"}],"wp:attachment":[{"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/media?parent=19047"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/tags?post=19047"},{"taxonomy":"service","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/service?post=19047"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.inovex.de\/de\/wp-json\/wp\/v2\/coauthors?post=19047"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}