Umsetzung von REST-Services

1. Technologieauswahl

Die IsyFact legt folgende Frameworks für die Umsetzung von REST-Services fest.

Tabelle 1. Frameworks für die Umsetzung
Framework Technologie-Stack Beschreibung

Spring Webflux

Java/Spring

Umsetzung von REST-Clients

(unter Nutzung von Apache HTTPComponents)

Spring MVC

Java/Spring

Umsetzung von REST-Services

(zur Nutzung mit Tomcat)

Angular Framework Modul: @angular/common/http

TypeScript/Angular

Umsetzung von REST-Clients

OpenAPI

technologie-unabhängig

Dokumentation der Service Schnittstelle und Erzeugung von Service und Client

2. Spring MVC im Vergleich zu Spring Webflux

Das Spring Framework stellt seit Version 5 Spring Webflux als reaktive Alternative zu Spring MVC bereit.

Mit Webflux ist es möglich, reaktive REST APIs zu implementieren. Beim reaktiven Programmierparadigma geht es um die Reaktion auf Veränderungen (Observer Pattern), im Fall von REST APIs um die Reaktion auf gesendete Daten. Das ist hilfreich, wenn man große Datenmengen (z. B. Mediendateien oder größere Ergebnismengen aus einer Datenbankabfrage) über das REST API übertragen möchte. Die Daten werden dann in mehreren Paketen gesendet, der Empfänger reagiert jeweils auf den Erhalt eines Pakets.

Der Hauptvorteil von Webflux liegt aber im geringeren Ressourcenverbrauch auf der Server Seite. Webflux basiert auf einem Event-Loop Mechanismus, während Spring MVC auf Thread Pools basiert. Der Performance Vorteil von Webflux macht sich insbesondere bei vielen gleichzeiten Service-Aufrufen und/oder der Übertragung größerer Datenmengen bei einem Service-Aufruf bemerkbar.

Trotzdem empfiehlt die IsyFact grundsätzlich, Spring MVC für die Umsetzung von REST-Services einzusetzen. Die Vorteile des reaktiven Programmierparadigmas erfüllen sich nur, wenn alle Teile der Umsetzung entsprechend gestaltet sind. Dies ist aktuell nicht der Fall.

Für REST-Clients wiederum empfiehlt die IsyFact die Verwendung des WebClient anstatt des RestTemplate, da letzteres nicht mehr aktiv weiterentwickelt wird.

Für die Anbindung von Angular-Clients enthält der Baustein Angular eine entsprechende Komponente.

3. Schnittstellendokumentation

Alle auf IsyFact basierten Anwendungen müssen ihre REST-Services mit der OpenAPI 3.0 Spezifikation beschreiben. Sowohl YAML als auch JSON sind als Format der Schnittstellendokumentation zulässig. Die IsyFact empfiehlt zur Erstellung der Schnittstellendokumentation den OpenAPI (Swagger) Editor.

3.1. Code-Generierung

Bei der Erstellung von REST-APIs gibt es grundsätzlich 2 Ansätze: Contract/API First oder Code First. Bei Contract/API First wird zunächst die Schnittstellenbeschreibung erstellt und daraus der Code (Server und Client) generiert. Bei Code First wird zuerst die API implementiert und mit Annotationen für die Schnittstellenbeschreibung versehen. Aus den Annotationen wird dann die Schnittstellenbeschreibung generiert.

Die IsyFact empfiehlt den Contract/API First Ansatz und sieht hierzu die Erstellung einer OpenAPI-Spezifikation vor.

Für die Generierung von Code empfiehlt die IsyFact den OpenAPI Generator.

3.2. Bereitstellen von generierten Clients

Neben dem Server können aus einer OpenAPI-Spezifikation auch Clients für diverse Technologie-Stacks generiert werden. Aus Convenience-Gründen wird empfohlen, dass Anbieter von Services fertig generierte Clients für die gängigen Technologie-Stacks zur Verfügung stellen: Java (Spring) und Typescript (Angular).

4. Verwendung von Transportobjekten

Verwendung von Transferobjekten

REST-Services verwenden ausschließlich Transferobjekte (Data Transfer Objects, DTOs).

Die DTOs werden ebenfalls innerhalb der Schnittstellenbeschreibung schematisch beschrieben.

Der Code für die DTOs wird daraus generiert.

Innerhalb der Schnittstellenbeschreibung des Service werden die Schemata der DTOs üblicherweise als Referenz mittels #ref eingebunden. Die Referenz kann sich dabei auf eine Beschreibung innerhalb derselben Datei beziehen oder auch auf eine externe Datei. Die Datei kann dabei sowohl über einen Dateipfad als auch über eine URL adressiert werden.

Listing 1. Beispiel aus Swagger Petstore
requestBody:
   content:
      application/json:
         schema:
            $ref: '#/components/schemas/Pet'

# [...]

components:
   schemas:
      Pet:
         name:
            type: string
            example: doggie