SpringDoc: API-Dokumentation nach OAS 3.0

Daniel Schleise, 8. Februar 2023
Lesezeit: 15 Minuten

Dokumentation ist häufig unbeliebt, aber maßgeblich in der Entwicklung, um Interagierenden die Verwendung und den Umgang mit einer API nahe zu bringen. Mit steigender Komplexität und Größe von Schnittstellen, steigt jedoch auch der Aufwand diese zu beschreiben. SpringDoc verspricht uns hierbei Erleichterung beim Erstellen und Visualisieren von Dokumentationen.

Was ist SpringDoc?

SpringDoc ist eine Bibliothek, die bei der Generierung von API Dokumentation im Spring-Kontext hilft. SpringDoc untersucht dazu die Applikation zur Laufzeit anhand von Spring-Konfigurationen, Klassenstrukturen und anderen Annotationen, um die Struktur und Beschreibung der API abzuleiten. SpringDoc erstellt eine API Dokumentation nach OpenAPI 3.0 Spezifikation (OAS 3.0) und generiert daraus eine interaktive Benutzeroberfläche (Swagger UI).

OpenAPI

Die OpenAPI-Spezifikation (ehemals Swagger-Spezifikation) ist ein Beschreibungsformat für REST-APIs. Mit einer OpenAPI-Datei wird die gesamte Schnittstelle beschrieben, einschließlich:

  • Verfügbare Endpunkte (z.B. /users) und Operationen auf jedem Endpunkt (z.B. GET /users, POST /users)
  • Ein- und Ausgabeparameter für jede Operation
  • Authentifizierungsmethoden
  • Kontaktinformationen, Lizenz, Nutzungsbedingungen und andere Informationen.

OpenAPI-Spezifikationen können in YAML oder JSON geschrieben werden. Das Format ist dabei sowohl für Menschen als auch für Maschinen leicht verständlich.

Hier im Blog haben wir uns bereits vor einiger Zeit mit dem Thema Swagger UI von SpringFox beschäftigt.

Weshalb nun SpringDoc statt SpringFox?

SpringFox ist lediglich mit SpringBoot 1&2 kompatibel, der letzte Release liegt 1½ Jahre zurück mit mehreren ungelösten Issues und scheint nicht mehr weiter entwickelt zu werden. SpringDoc hingegen ist mit SpringBoot in den Versionen 1 bis 3 kompatibel und wird stetig weiterentwickelt.

SpringFox bietet Support für die Spezifikationen Swagger 1.2, OAS 2.0 & OAS 3.0. SpringDoc ist dagegen auf OAS 3.0 zugeschnitten. Was sind also die Änderungen von OAS 3.0 zu OAS 2.0?

OAS 3.0 Neuerungen

Sicherheitsdefinitionen

Es gibt einige wichtige Änderungen, die sich darauf auswirken, wie Sicherheitsanforderungen in OAS 3 abgebildet werden. Änderungen im Sicherheitskontext umfassen:

  • securityDefinitions wurden in securitySchemes umbenannt und in die Komponenten verschoben.
  • type: basic wurde durch type: http und scheme: basic ersetzt.
  • Der neue Typ: http ist ein Oberbegriff-Typ für alle HTTP-Sicherheitsschemata, einschließlich Basic, Bearer und andere; das Schlüsselwort scheme gibt den Schematyp an.
  • Unterstützung für OpenID Connect Discovery hinzugefügt.
  • OAuth 2-Sicherheitsschemata können jetzt mehrere Flows definieren.
  • OAuth-2-Flows wurden umbenannt, damit sie der OAuth-2-Spezifikation entsprechen. Der „accessCode“ heißt jetzt „authorizationCode“ und „application“ heißt jetzt „clientCredentials“.

Strukturell

/uploads/OAS_2_OAS_3_vergleich_3542aac85d.jpg

OAS 3.0 führt eine neue, vereinfachte Struktur ein. Diese soll es einfacher machen, OAS-Definitionen zu schreiben und darin zu navigieren. Die Struktur kombiniert einige der bestehenden Objekte aus OAS 2.0, standardisiert die für verschiedene Teile der Spezifikation verwendeten Benennungen und führt sogar neue Objekte ein, um die Wiederverwendbarkeit von Komponenten innerhalb von OAS 3.0 zu erweitern. Die Anzahl dieser stieg dabei von 4 auf 9.

Vereinfachung und bessere Wiederverwendbarkeit klingt vielversprechend im Hinblick auf API-Dokumentation. Nun sollte die Umsetzung von SpringDoc dies auch in der Praxis bestätigen.

Java Implementierung

Um SpringDoc in einem Java Spring Boot Projekt zu nutzen muss in einem Maven-Projekt lediglich die pom.xml um folgende Abhängigkeit ergänzt werden.

Copy
<!--SpringBoot 1&2-->
<dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-ui</artifactId>
      <version>1.6.14</version>
</dependency>

<!--SpringBoot 3-->
<dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
      <version>2.0.2</version>
</dependency>

Dadurch ist SpringDoc eingebunden und generiert automatisch eine API-Dokumentation nach OpenAPI 3 Spezifikation, die über http://server:port/context-path/v3/api-docs im JSON Format zur Verfügung steht. Sowie ein interaktives Swagger-User-Interface unter http://server:port/context-path/swagger-ui.html /uploads/Spring_Doc_plainsite_f650a514d2.PNG

Dokumentation

SpringDoc enthält die nötigen Abhängigkeiten für die Swagger 3 Annotationen und bietet darüber hinaus auch über eigene Properties die Möglichkeit, die API-Dokumentation zu individualisieren.

Meta-Informationen

Im Folgenden werden Meta-Informationen für die API deklariert

Copy
@Bean
public OpenAPI springUserOpenAPI() {
    return new OpenAPI()
        .info(new Info()
            .title("SpringUser API")
            .description("Spring user sample application")
            .version("v0.0.1")
            .license(new License()
                .name("Apache 2.0")
                .url("https://springdoc.org")))
        .servers(list.of(new Server().url(serverUrl).description(ServerDescription)));
}

/uploads/Spring_Doc_site_with_Informations_cebc99c0c0.PNG

Sicherheitsdefinitionen

Globale Sicherheitsanforderungen lassen sich wie folgt Konfigurieren

Basic-Authentifizierung

Copy
@Bean
public OpenAPI springUserOpenAPI() {
    return new OpenAPI()
        .info(new Info()
            .title("SpringUser API")
            .description("Spring user sample application")
            .version("v0.0.1")
            .license(new License()
                .name("Apache 2.0")
                .url("https://springdoc.org")))
         .servers(List.of(new Server().url(serverUrl).description(ServerDescription)))
         .components(new Components()
             .addSecuritySchemes("BasicAuth", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("Basic")))
             .security(List.of(new SecurityRequirement()
                 .addList("BasicAuth")));
}

OAuth2

Copy
@Bean
public OpenAPI springUserOpenAPI() {
    return new OpenAPI()
        .info(new Info()
            .title("SpringUser API")
            .description("Spring user sample application")
            .version("v0.0.1")
            .license(new License()
                .name("Apache 2.0")
                .url("https://springdoc.org")))
        .servers(List.of(new Server().url(serverUrl).description(ServerDescription)))
        .components(new Components()
            .addSecuritySchemes("OAuth2", new SecurityScheme().type(SecurityScheme.Type.OAUTH2)
                .flows(new OAuthFlows().authorizationCode(
                    new OAuthFlow().authorizationUrl(authorizationUrl)
                        .tokenUrl(tokenUrl))
                        .clientCredentials(
                            new OAuthFlow().tokenUrl(tokenUrl)
                                .scopes(new Scopes()
                                .addString("Scope", "Description"))))))
        .security(List.of(new SecurityRequirement()
            .addList("OAuth2")));
}

OpenIDConnect

Copy
@Bean
public OpenAPI springUserOpenAPI() {
    return new OpenAPI()
        .info(new Info()
            .title("SpringUser API")
            .description("Spring user sample application")
            .version("v0.0.1")
            .license(new License()
                .name("Apache 2.0")
                .url("https://springdoc.org")))
        .servers(List.of(new Server().url(serverUrl).description(ServerDescription)))
        .components(new Components()
            .addSecuritySchemes("OIDC",new SecurityScheme()
                .type(SecurityScheme.Type.OPENIDCONNECT)
                .openIdConnectUrl(openIdConnectUrl)))
        .security(List.of(new SecurityRequirement()
            .addList("OIDC")));
}

/uploads/Spring_Doc_site_with_Informations_and_authorisation_authorisation_405e298242.PNG

Operationen

Nachdem die Meta-Informationen gesetzt sind und die Sicherheitsanforderungen für die API-Dokumentation konfiguriert wurden, bleibt noch der Kern der Dokumentation: die Operationen zu beschreiben. Wie diese Beschrieben werden hat Paul bereits in seinem lesenswerten Beitrag über Swagger erklärt.

Fazit

In der agilen Softwareentwicklung ist stetige Weiterentwicklung und Evaluierung vom Status quo essentiell, um das Momentum beizubehalten. Aufwendige Dokumentationsprozesse, wären dafür hinderlich. So ist es für uns wichtig, dass die Tools, die wir in diesem Bereich nutzen, die bewährten Neuerungen in der Softwareentwicklung verkörpern, ohne Einbußen in der Agilität in Kauf nehmen zu müssen. SpringDoc tut dies, in dem es den aktuellen OpenAPI Standard für API-Dokumentation umsetzt und dafür die bestehende Spring-Infrastruktur nutzt. Gerade die Beschreibung der Operationen durch die Swagger-Annotationen, macht dabei das Dokumentieren im Code sehr komfortabel im Entwickleralltag und macht Dokumentation nicht mehr zur lästigen Fleißarbeit.

Ich selbst durfte SpringDoc in mehreren Projekten einsetzen und dabei von der Flexibilität, die SpringDoc bietet, profitieren. Es gab keinen Fall, den ich damit nicht abdecken konnte. Sicherlich wird die Swagger-UI im ein oder anderen Fall in der Praxis zur Klärung der Funktionalitäten beitragen. Ob für andere Entwickler oder Kunden, verständlich ist sie für beide.

author image
Daniel Schleise
Student Wirtschaftsinformatik, 5. Semester
SpringDoc ist nur eines von vielen Themen, in die ich mich selbständig während meiner Praxisphase einarbeiten durfte. Die Einarbeitung in solche Themen zeigen, wie die verschiedenen theoretischen Zahnräder aussehen, ineinander greifen, Projekte zum Laufen und voran bringen.