OpenAPI in der Praxis (2) Datenbank um API und Dokumentation erweitern

Von Mirco Lang 5 min Lesedauer

Die API-Definition als YAML-Datei ist geschafft – nun geht es an die Umsetzung und die Dokumentation - mithilfe von Flask und ReDoc.

OpenbAPI in der Praxis: Demo-Datenbank mit API und Dokumentation ausstatten.(Bild:  © deagreez - stock.adobe.com)
OpenbAPI in der Praxis: Demo-Datenbank mit API und Dokumentation ausstatten.
(Bild: © deagreez - stock.adobe.com)

Im ersten Teil des Artikels haben wir den Weg von einer SQL-Datenbank über dessen exportiertes Schema hin zur passenden OpenAPI-Spezifikation in Form einer YAML-Datei gezeigt. Die API selbst ist damit im Grunde schon fertig – aber es fehlt noch eine App, die diese API auch tatsächlich nutzt und Daten in der Datenbank manipuliert.

Diese App ist natürlich nur eine Art Demo, die Sie Ihren Nutzern zwar spendieren können, aber nicht müssen – letztlich soll die API ja dafür sorgen, dass Nutzer auf ihre eigene Art auf die Daten(bank) zugreifen und eigene Apps entwickeln können.

Für die Demo-Implementierung sorgen hier Python und das Framework Flask. Die automatische Dokumentation wird im ReDoc-Format per CLI-Tool erstellt.

API implementieren

Natürlich wird das hier keine Einführung in Python oder Flask – und genau genommen müssen Sie beides gar nicht beherrschen, denn mit der API-YAML gibt es eine sehr eindeutig und klar strukturierte Basis. Die Anforderungen an die App sind sehr überschaubar und somit bieten sich für diese Aufgabe wieder KI-Helfer an. Selbst ChatGPT, das nicht für das Programmieren optimiert ist, eignet sich hierfür. Aber Sie sollten sich auf ein paar Nachfragen und Korrekturen einstellen.

Der Flask-Code besteht aus zwei wesentlichen Komponenten. Zunächst mal die Verbindung zur Datenbank:

# Database connectiondb = mysql.connector.connect(   host="192.168.178.200",   user="mirco",   password="mypassword",   database="mystuff")

Diese Verbindung zwischen Theorie (API-Spezifikation) und Praxis (Datenverarbeitung) mag unscheinbar wirken, doch dieser Part taucht in den vom Swagger-Generator erstellten Stubs nicht auf.

Und nun erinnern Sie sich an die Pfade aus der API-Definition in der YAML-Datei (siehe OpenAPI in der Praxis - Teil 1):

/useful_things:   get:      summary: Get a list of useful things

In Flask werden diese Pfade aufgegriffen und per App wird Routing mit Datenbankoperationen verknüpft:

cursor = db.cursor(dictionary=True)@app.route('/useful_things', methods=['GET'])   def get_useful_things():      cursor.execute("SELECT * FROM useful_things")      results = cursor.fetchall()      return jsonify(results)

Für den Pfad „/useful_things“ wird hier für die Methode GET die SQL-Operation „SELECT * FROM useful_things“ definiert – also ein Auflisten aller Einträge in der Tabelle „useful_things“ aus unserer Mystuff-Testdatenbank.

Alle weiteren Pfade werden entsprechend umgesetzt, bis CRUD-Operationen für sämtliche Spalten und gegebenenfalls Tabellen zur Verfügung stehen.

Und damit steht eine echte, einsatzbereite API für die SQL-Datenbank zur Verfügung, die Sie natürlich auch direkt testen können:

curl -X GET http://192.168.178.200:5000/useful_things

Auch hier sehen Sie wieder den Pfad (useful_things) sowie die Methode (GET), so dass serverseitig nun die Flask-Funktion ausgeführt wird, die wiederum das Ergebnis der SQL-Abfrage im JSON-Format ausliefert.

Nochmal die Schritte bis hierher:

  • Datenbank besteht.
  • Datenbankschema wird exportiert.
  • Aus dem Schema wird die API-Spezifikation abgeleitet.
  • Aus der Spezifikation wird eine Flask-Server-Anwendung entwickelt.
  • cURL dient als Client zum Konsumieren der API.

Nun fehlt ein weiterer wichtiger Schritt. Man will als Benutzer nicht den gesamten Quellcode durchsuchen müssen, um herauszufinden, wie man einen richtigen curl-Befehl formuliert. Stattdessen sollte die Dokumentation diesen Befehl direkt bereitstellen.

Übrigens: Der Code-Generator von Swagger kann natürlich auch Client-Stubs generieren. Wenn Sie also nicht Nutzer einfach mit Standard-Tools wie cURL auf die API loslassen wollen, sondern selbst etwa einen schicken Python-Client anbieten möchten, würde sich so ein Client-Stub als Ausgangsbasis anbieten.

Dokumentation erstellen

Die Dokumentation soll nun mit ReDoc erstellt werden. Und um ganz kurz etwaige Begriffsschwierigkeiten auszuschließen: Redoc ist ein Open-Source-Tool, Redocly ein kommerzielles Angebot, das auf Redoc aufbaut. Praktisch wird mit dem Programm Redocly CLI gearbeitet, das vormals redoc-cli hieß – ebenso wie OpenAPI früher unter Swagger lief, was heute als Tool-Sammlung verstanden wird, spendiert von SmartBear Software.

Redocly CLI ist ebenfalls Open Source und kann zum Beispiel über NPM installiert werden:

npm install @redocly/cli -g

Und jetzt wird es simpel für ein Tool im Dev-Umfeld:

redocly build-docs my-api-specs.yaml

Mit diesem einfachen Befehl wird aus der API-YAML eine statische HTML-Datei mit der fertigen Dokumentation erzeugt:

API-Dokumentation via API-Definition.(Bild:  Redocly)
API-Dokumentation via API-Definition.
(Bild: Redocly)

Die Dokumentation unterschlägt jedoch bislang sämtliche Code-Beispiele. In der rechten Spalte finden sich lediglich Angaben zum Request Body.

Auch an dieser Stelle gibt es wieder Tools, die Code-Beispiele automatisch generieren können, aber letztlich läuft über Erweiterungen der Pfad in der API-YAML. Schließlich geht es bei Redoc nicht darum neuen Content zu erzeugen, sondern vorhandenen Content zu rendern.

Zu den einzelnen Methoden (GET, POST etc.) eines Pfads werden dann gleichwertig „x-codeSamples“ gesetzt. Hier mal der komplette Eintrag für die GET-Anfrage im Pfad „/useful_things“:

Jetzt Newsletter abonnieren

Täglich die wichtigsten Infos zu Cloud Computing

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung. Die Einwilligungserklärung bezieht sich u. a. auf die Zusendung von redaktionellen Newslettern per E-Mail und auf den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern (z. B. LinkedIn, Google, Meta).

Aufklappen für Details zu Ihrer Einwilligung
paths:   /useful_things:     get:       summary: Get a list of useful things       responses:         '200':           description: A JSON array of useful things           content:             application/json:               schema:                 type: array                 items:                   $ref: '#/components/schemas/UsefulThing'       x-codeSamples:           - lang: 'cURL'             label: 'cURL'             source: |               curl --request GET \               --url 'localhost:5000/useful_things' \               --header 'content-type: application/json' \           - lang: 'HTTPie'             label: 'HTTPie'             source: |               http localhost:5000/useful_things \

Sie können hier beliebig viele Beispiele hinterlegen, cURL sollte dabei sicherlich nie fehlen. Moderner und speziell für API-Interaktionen entwickelt wurde HTTPie, welches wir Ihnen auch schon separat vorgestellt haben.

Die Code-Beispiele beschränken sich auf die Angaben zu Sprache (lang), Überschrift (label) und Code (source) selbst. Und schon bekommen Ihre Nutzer ganz konkrete Hinweise, wie sie mit der API sprechen können:

Redoc-Doku mit Code-Beispielen.(Bild:  Redoc)
Redoc-Doku mit Code-Beispielen.
(Bild: Redoc)

Und um die API in Aktion zu zeigen, hier eine HTTPie-Abfrage:

API-Abfrage per HTTPie.(Bild:  HTTPie)
API-Abfrage per HTTPie.
(Bild: HTTPie)

Ein kleiner Hinweis: Im Screenshot sehen Sie vor dem HTTPie-Befehl (im Terminal „http“) noch „winpty“: Erst mit dieser Windows-eigenen Kompatibilitätsschicht wird HTTPie in der Windows-Bash in diesem Fall korrekt ausgeführt – andernfalls hängt es einfach.

Fazit

Im Grunde ist es simpel, einer bestehenden Anwendung, oder besser gesagt einer Datenquelle, eine OpenAPI-REST-Schnittstelle zu verpassen. Die spannendsten Aspekte sind hier die folgenden: Das Erzeugen einer API-Spezifikation aus einem Datenbankschema, das automatische Generieren einer Demo-/Stub-Anwendung aus der API-Spezifikation via App Routing und letztlich natürlich das unglaublich triviale Erzeugen hübscher API-Dokumentationen via Redocly CLI.

Wenn Sie dieses Konzept, hier händisch durchexerziert, einmal verinnerlicht haben, wird es sehr viel einfacher, sich mit dem großen Tool- und Service-Angebot rund um OpenAPI auseinanderzusetzen. Und im Grunde läuft es nur auf eine simple Verbindung hinaus: Die Theorie in Form von definierten Pfaden und zugehörigen Request-Operationen und der Praxis in Form von Funktionen, die jedem Pfad-Request-Operator-Paar zugeordnet werden.

(ID:50157033)