18 Einführung in OpenAPI

18.1 Einführung

OpenAPI, früher bekannt als Swagger, ist eine offene Spezifikation zur Beschreibung von RESTful APIs. Es bietet einen standardisierten Weg, APIs zu definieren, sodass sowohl Menschen als auch Maschinen diese verstehen, dokumentieren, testen und nutzen können. OpenAPI erleichtert die Entwicklung, Wartung und Integration von APIs erheblich, indem es klare Verträge zwischen Dienstleistern und Verbrauchern schafft.

18.2 Historischer Kontext

Die Entwicklung von OpenAPI begann ursprünglich mit dem Swagger-Projekt, das von Tony Tam ins Leben gerufen wurde. Swagger gewann schnell an Popularität als Werkzeug zur Dokumentation und Visualisierung von APIs. Im Jahr 2016 übernahm die Linux Foundation das Projekt und gründete die OpenAPI Initiative (OAI), um die Spezifikation als offenen Standard weiterzuentwickeln. Seitdem hat sich OpenAPI zu einem weit verbreiteten Standard in der API-Entwicklung etabliert.

18.3 Grundlegende Konzepte von OpenAPI

  1. OpenAPI Specification (OAS)

    Die OpenAPI Specification ist das Herzstück von OpenAPI. Sie definiert die Struktur und die Bestandteile einer API-Dokumentation. Die Spezifikation kann in YAML- oder JSON-Format verfasst werden und umfasst mehrere Schlüsselkomponenten:

  2. Endpoints und Operationen

    Jeder Endpunkt (path) in einer OpenAPI-Spezifikation repräsentiert eine Ressource oder eine Funktion der API. Innerhalb jedes Endpunkts werden verschiedene Operationen (HTTP-Methoden wie GET, POST, PUT, DELETE) definiert, die beschreiben, welche Aktionen auf dieser Ressource durchgeführt werden können.

  3. Schemas

    Schemas definieren die Struktur der Daten, die von der API gesendet und empfangen werden. Sie basieren auf JSON Schema und ermöglichen die präzise Beschreibung von Datenmodellen, einschließlich Typen, Eigenschaften, Validierungen und Beziehungen.

  4. Sicherheitsmechanismen

    OpenAPI unterstützt verschiedene Authentifizierungs- und Autorisierungsmethoden, wie API-Schlüssel, OAuth2 und JWT. Diese werden in der Spezifikation definiert und können für einzelne Endpunkte oder global für die gesamte API angewendet werden.

18.4 Vorteile von OpenAPI

18.5 Struktur einer OpenAPI-Spezifikation

Eine typische OpenAPI-Spezifikation besteht aus den folgenden Hauptkomponenten:

openapi: 3.0.1
info:
  title: Bücher API
  description: Eine API zur Verwaltung von Büchern.
  version: 1.0.0
servers:
  - url: https://api.beispiel.com/v1
paths:
  /books:
    get:
      summary: Liste aller Bücher abrufen
      responses:
        '200':
          description: Erfolgreiche Antwort
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Book'
    post:
      summary: Ein neues Buch erstellen
      requestBody:
        description: Buchdaten
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Book'
      responses:
        '201':
          description: Buch erstellt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'
components:
  schemas:
    Book:
      type: object
      properties:
        id:
          type: integer
          format: int64
        title:
          type: string
        author:
          type: string
      required:
        - title
        - author

18.6 Erläuterung der Komponenten

18.7 Integration von OpenAPI in Spring Boot

Spring Boot bietet mehrere Möglichkeiten, OpenAPI in Anwendungen zu integrieren, um die API-Dokumentation und -Entwicklung zu erleichtern. Eine der beliebtesten Bibliotheken hierfür ist Springdoc OpenAPI.

18.7.1 Schritt 1: Abhängigkeit hinzufügen

Fügen Sie die folgende Abhängigkeit zu Ihrer pom.xml hinzu:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.6.14</version>
</dependency>

18.7.2 Schritt 2: Automatische Generierung der OpenAPI-Dokumentation

Springdoc OpenAPI scannt automatisch Ihre REST-Controller und generiert die OpenAPI-Spezifikation sowie eine interaktive Swagger UI zur Visualisierung und Interaktion mit Ihrer API.

18.7.3 Schritt 3: Zugriff auf die Swagger UI

Nach dem Start Ihrer Anwendung können Sie die Swagger UI unter http://localhost:8080/swagger-ui.html oder http://localhost:8080/swagger-ui/index.html aufrufen. Diese Oberfläche ermöglicht es Ihnen, die API-Endpunkte zu erkunden, Anfragen zu senden und Antworten zu überprüfen.

18.8 Beispiel eines REST-Controllers mit OpenAPI-Annotationen

import org.springframework.web.bind.annotation.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;

@RestController
@RequestMapping("/api/books")
public class BookController {

    @Operation(summary = "Liste aller Bücher abrufen")
    @ApiResponse(responseCode = "200", description = "Erfolgreiche Antwort",
        content = @Content(mediaType = "application/json",
        schema = @Schema(implementation = Book.class)))
    @GetMapping
    public List<Book> getAllBooks() {
        // Implementierung
    }

    @Operation(summary = "Ein Buch anhand der ID abrufen")
    @ApiResponse(responseCode = "200", description = "Buch gefunden",
        content = @Content(mediaType = "application/json",
        schema = @Schema(implementation = Book.class)))
    @ApiResponse(responseCode = "404", description = "Buch nicht gefunden")
    @GetMapping("/{id}")
    public ResponseEntity<Book> getBookById(@PathVariable Long id) {
        // Implementierung
    }

    @Operation(summary = "Ein neues Buch erstellen")
    @ApiResponse(responseCode = "201", description = "Buch erstellt",
        content = @Content(mediaType = "application/json",
        schema = @Schema(implementation = Book.class)))
    @PostMapping
    public ResponseEntity<Book> createBook(@RequestBody Book book) {
        // Implementierung
    }

    // Weitere Methoden
}

18.8.1 Erläuterung der Annotationen

18.8.2 Definieren von Datenmodellen

import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "Repräsentiert ein Buch im System")
public class Book {

    @Schema(description = "Eindeutige ID des Buches", example = "1")
    private Long id;

    @Schema(description = "Titel des Buches", example = "Spring Boot in Action")
    private String title;

    @Schema(description = "Autor des Buches", example = "Craig Walls")
    private String author;

    // Getter und Setter
}

18.9 Contract First vs. Code First

Bei der API-Entwicklung gibt es zwei Hauptansätze zur Nutzung von OpenAPI:

  1. Code First: Der Entwickler schreibt zunächst den Anwendungscode (Controller, Modelle) und generiert daraus die OpenAPI-Spezifikation. Dies ist oft schneller für kleinere Projekte oder wenn die API sich häufig ändert.

  2. Contract First: Die API-Spezifikation wird zuerst erstellt, und der Anwendungscode wird basierend auf dieser Spezifikation generiert. Dies fördert eine klare Trennung zwischen API-Design und Implementierung und ist besonders nützlich in großen Teams oder bei der Zusammenarbeit mit externen Partnern.

18.9.1 Beispiel: Contract First-Ansatz mit OpenAPI Generator

18.9.1.1 Schritt 1: OpenAPI-Spezifikation erstellen

Erstellen Sie eine api.yaml-Datei mit der Definition Ihrer API.

openapi: 3.0.1
info:
  title: Bücher API
  version: 1.0.0
servers:
  - url: http://localhost:8080/api
paths:
  /books:
    get:
      summary: Liste aller Bücher abrufen
      responses:
        '200':
          description: Erfolgreiche Antwort
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Book'
    post:
      summary: Ein neues Buch erstellen
      requestBody:
        description: Buchdaten
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Book'
      responses:
        '201':
          description: Buch erstellt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Book'
components:
  schemas:
    Book:
      type: object
      properties:
        id:
          type: integer
          format: int64
        title:
          type: string
        author:
          type: string
      required:
        - title
        - author

18.9.1.2 Schritt 2: Code-Generierung mit OpenAPI Generator

Verwenden Sie den OpenAPI Generator, um Server-Stubs und Modelle zu generieren.

openapi-generator generate -i api.yaml -g spring -o generated-server

18.9.1.3 Schritt 3: Implementierung der Geschäftslogik

Füllen Sie die generierten Controller-Methoden mit der eigentlichen Geschäftslogik.

18.10 Vorteile des Contract First-Ansatzes

18.11 Best Practices für die Nutzung von OpenAPI

  1. Versionskontrolle der Spezifikation

    Speichern Sie Ihre OpenAPI-Spezifikation im gleichen Repository wie Ihren Code, um Änderungen nachverfolgen zu können.

  2. Konsistente Nutzung von Tags und Schemas

    Verwenden Sie konsistente Namenskonventionen und Strukturen in Ihren Schemas und Tags, um die Lesbarkeit und Wartbarkeit zu erhöhen.

  3. Automatisierte Tests

    Implementieren Sie Tests, die sicherstellen, dass die API-Implementierung mit der Spezifikation übereinstimmt.

  4. Integration in die CI/CD-Pipeline

    Automatisieren Sie die Code-Generierung und Validierung der Spezifikation in Ihrer Continuous Integration/Continuous Deployment (CI/CD)-Pipeline.

  5. Dokumentation und Pflege

    Halten Sie Ihre OpenAPI-Spezifikation stets aktuell und dokumentieren Sie alle Änderungen sorgfältig, um die Qualität der API-Dokumentation zu gewährleisten.

18.12 Integration mit Build-Tools

18.12.1 Maven Plugin Beispiel

Fügen Sie das OpenAPI Generator Maven Plugin zu Ihrer pom.xml hinzu, um die Code-Generierung während des Build-Prozesses zu automatisieren.

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>5.4.0</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec>
                <generatorName>spring</generatorName>
                <output>${project.build.directory}/generated-sources</output>
            </configuration>
        </execution>
    </executions>
</plugin>

18.13 Best Practices für die Nutzung von OpenAPI in Spring Boot

  1. Nutzen Sie Springdoc OpenAPI für nahtlose Integration

    Springdoc OpenAPI bietet eine einfache Integration mit Spring Boot und ermöglicht die automatische Generierung der OpenAPI-Dokumentation basierend auf Ihren REST-Controllern.

  2. Verwenden Sie aussagekräftige Beschreibungen und Beispiele

    Ergänzen Sie Ihre API-Spezifikation mit detaillierten Beschreibungen und Beispielen, um die Verständlichkeit und Benutzerfreundlichkeit zu erhöhen.

  3. Verwalten Sie API-Versionen sorgfältig

    Planen Sie eine klare Versionierungsstrategie, um Kompatibilitätsprobleme zu vermeiden und die Weiterentwicklung Ihrer API zu erleichtern.

  4. Nutzen Sie Sicherheitsdefinitionen

    Definieren Sie Authentifizierungs- und Autorisierungsschemata in Ihrer OpenAPI-Spezifikation, um die Sicherheitsanforderungen Ihrer API klar zu kommunizieren.

  5. Erstellen Sie konsistente und wiederverwendbare Schemas

    Vermeiden Sie Redundanzen, indem Sie wiederverwendbare Schemas für häufig genutzte Datenstrukturen definieren.

18.14 tl;dr

OpenAPI ist ein standardisiertes Format zur Beschreibung von RESTful APIs, das die Entwicklung, Dokumentation und Integration von APIs vereinfacht. Mit Komponenten wie Endpunkten, Schemas und Sicherheitsdefinitionen ermöglicht OpenAPI klare Verträge zwischen Dienstleistern und Verbrauchern. Durch die Integration mit Tools wie Springdoc OpenAPI und dem OpenAPI Generator können Entwickler automatisch Client- und Server-Code sowie interaktive Dokumentationen erstellen. OpenAPI fördert die Konsistenz, Automatisierung und Wartbarkeit von APIs, wodurch es zu einem unverzichtbaren Bestandteil moderner API-Entwicklung geworden ist.