Zurück zur WebseiteInsights

JSON Schema everywhere

By Dominik Horn
Published in BPM
September 29, 2022
4 min read
JSON Schema everywhere

Einleitung

In diesem Blogpost werfen wir einen Blick auf die Verwendung von JSON Schema bei der Digitalisierung von Prozessen mit BPMN. Dabei werden verschiedene Anwendungsszenarien vorgestellt - von der Modellierung von Formularen bei Benutzeraufgaben bis hin zur Validierung und Serialisierung von Daten im Backend. Zudem werden Implementierungsansätze mit Camunda 7 betrachtet.

Was ist JSON Schema überhaupt?

JSON ist ein einfaches, textbasiertes Datenformat, das im Web für viele Datenübertragungen genutzt wird. JSON Schema ist ein dazugehöriger IETF-Standard (Internetstandard), der es ermöglicht, JSON-Daten zu beschreiben und zu validieren. Er bietet verschiedene Vorteile, u.A.:

  • Beschreibung der vorhandenen Datenformate
  • Eine Dokumentation, die von Menschen und Maschinen gelesen werden kann
  • Validierung von Daten

Nehmen wir das folgende JSON, das aus den Werten Vorname, Nachname und Alter besteht:

{
  "firstName": "John",
  "lastName": "Doe",
  "age": 21
}

Das dazugehörige Schema kann unterschiedliche Ausprägungen haben. Es kann sich bspw. um eine Person mit den folgenden Eigenschaften handeln:

  • Vorname
  • Nachname
  • Alter
  • Größe

Ein passendes JSON Schema könnte wie folgt definiert werden:

{
  "title": "Person",
  "type": "object",
  "required": [ "firstName", "lastName", "age" ],
  "properties": {
    "firstName": {
      "type": "string",
      "description": "The person's first name."
    },
    "lastName": {
      "type": "string",
      "description": "The person's last name."
    },
        "height": {
      "type": "integer",
      "description": "The person's height in cm."
    },
    "age": {
      "description": "Age in years which must be equal to or greater than zero.",
      "type": "integer",
      "minimum": 0
    }
  }
}

Es handelt sich um eine Person ****mit dem type object . Unter properties werden die Attribute des Objektes definiert. Ein Attribut besteht dabei immer aus einem type und kann zusätzlich mit einer Beschreibung (description) versehen werden.

JSON Schema bietet zahlreiche verschiedene Arten der Validierung an. Attribute vom Typ integer können bspw. mit einer Eigenschaft minimium versehen werden. Bei einer Person ist dies hilfreich, da ein negatives Alter nicht möglich ist.

Auf Ebene der Person ist zusätzlich ein required Array definiert. Dieses enthält Eigenschaften der Person, die zwingend vorhanden sein müssen. Die height ist es nicht, weshalb das zuvor definierte JSON gültig ist.

Mehr über JSON Schema kannst Du unter https://json-schema.org/ erfahren. Dort findest Du auch Tutorials und weitere Links.

JSON Schema in Formularen

Doch was nutzt uns die Definition eines Schemas für die Modellierung von Formularen? Die Idee dahinter ist einfach: Wir können ein Schema nutzen, um Daten im Frontend zu visualisieren und das gleiche Schema verwenden, um diese im Backend zu validieren.

Es gibt zahlreiche Bibliotheken für unterschiedliche Frameworks, die aus einem JSON Schema ein Formular zur Laufzeit generieren.

  • https://jsonforms.io/ ist ein Open-Source-Projekt der Eclipse Foundation, das es ermöglicht, über verschiedene Renderer Formulare aus JSON Schema zu generieren. Es ist kompatibel mit den Frameworks React, Vue und Angular. Dabei kann zusätzlich ein UI-Schema definiert werden, um das Datenmodell frei von Oberflächenkonfigurationen zu halten.
  • https://github.com/koumoul-dev/vuetify-jsonschema-form ist eine Vue-Library für das UI-Framework Vuetify, die nur ein JSON Schema für die Anzeige benötigt. Dadurch können sehr schnell Formulare erstellt werden. Werden jedoch größere Anpassungen für die UI gemacht, kann das Schema schnell komplex werden.
  • https://github.com/rjsf-team/react-jsonschema-form ist eine React-Library, die verschiedene UI-Bibliotheken unterstützt, darunter Material UI, Bootstrap und Semantic UI. Bei dieser Library kann ebenfall ein UI-Schema definiert werden, um das JSON Schema nicht mit Oberflächenkonfigurationen zu vermischen.

Um das Beispiel einfach zu halten, verwenden wir im folgenden die Bibliothek Vuetify JSON Schema Form. Das Schema entspricht, mit ein paar kleineren Anpassungen, dem Personenschema aus dem vorangegangen Abschnitt.

{
  "type": "object",
    "required": [ "firstName", "lastName", "age" ],
  "properties": {
    "firstName": {
        "type": "string",
        "title": "Firstname",
        "description": "The person's first name."
    },
        "lastName": {
      "type": "string",
      "title": "Lastname",
        "description": "The person's last name."
    },
    "address": {
      "type": "string",
      "title": "Address",
      "x-display": "textarea",
            "description": "The person's address."
    },
    "height": {
      "type": "integer",
      "title": "Height",
            "description": "The person's height.",
      "x-display": "slider",
      "minimum": 30,
      "maximum": 240
    },
    "age": {
      "type": "integer",
      "title": "Age",
            "description": "The person's age.",
            "minimum": 0
    }
  }
}

Der Unterschied zum JSON Schema der Person sind die title und x-display Attribute, die von der Library beim Rendering des Formulars verwendet werden. Als Ergebnis liefert die Library folgendes Formular:

Formular
Formular

Es gibt noch zahlreiche Möglichkeiten, um Anpassungen an der UI vorzunehmen oder eigene Input Controls bereitzustellen. Mehr dazu kann in der Dokumentation der Library nachgelesen werden: https://koumoul-dev.github.io/vuetify-jsonschema-form/latest/

Dieses Schema kann anschließend mit einer Benutzeraufgabe verknüpft werden. In DigiWF bei der Landeshauptstadt München haben wir dafür eine JSON Schema Registry implementiert (https://github.com/it-at-m/digiwf-core/tree/dev/digiwf-schema-registry) und verknüpfen das passende Schema über eine Input-Variable in der Benutzeraufgabe.

User Task BPMN
User Task BPMN

Das Frontend lädt sich dann das entsprechende Schema und zeigt die Daten dazu passend an. Für die Modellierung von Formularen haben wir in DigiWF einen Drag&Drop-Formular-Builder erstellt: https://github.com/it-at-m/digiwf-core/tree/dev/digiwf-apps/packages/components/digiwf-form-builder Bei Miragon haben wir zudem ein VS-Code-Plugin bereitgestellt, das die Modellierung von Formularen in der IDE ermöglicht: https://github.com/Miragon/vs-code-vuetify-jsonschema-builder

Doch wie können wir bei der Ausführung von Prozessen sicherstellen, dass ein Benutzer nur auf bestimmte Daten Lese- und Schreibzugriff hat?

Validierung und Serialisierung im Backend

Um zu verstehen wie das Problem gelöst werden kann, schauen wir uns zunächst einmal das Zusammenspiel der einzelnen Komponenten in DigiWF an, wenn ein Benutzer eine Aufgabe öffnet.

Aufgabe laden
Aufgabe laden

Wenn ein Benutzer eine Aufgabe in der Aufgabenliste öffnet wird ein Request an die Engine gesendet. Diese lädt sich anhand des Input Parameters app_schema_task_key das entsprechende Schema aus der Registry. Anhand des Schemas werden die Daten aus der Prozessinstanz extrahiert und schlussendlich an die Tasklist zurückgesendet. Es wird somit über die Definition des Schemas eingeschränkt, auf welche Daten ein Benutzer Zugriff hat. Dabei wird im Backend das gleiche Schema verwendet wie im Frontend.

Ein weiterer Anwendungsfall, der etwas komplexer ist, ist das Abschließen von Aufgaben, das im folgenden Schaubild visualisiert ist:

Aufgabe abschließen
Aufgabe abschließen

Wenn ein Benutzer eine Aufgabe abschließt, werden im nächsten Schritt die Daten anhand des Schemas im Backend validiert und gefiltert. Damit wird verhindert, dass über die API Daten eingespielt werden, die ein Benutzer nicht schreiben darf oder die einen falschen Datentyp haben.

Danach werden die bisherigen Daten aus der Engine geladen. Der Grund dafür ist, dass es im JSON Schema verschachtelte Objektstrukturen geben kann:

{
  "title": "Person",
  "type": "object",
  "required": [ "firstName", "lastName", "age" ],
  "properties": {
    "firstName": {
      "type": "string",
      "description": "The person's first name."
    },
    "lastName": {
      "type": "string",
      "description": "The person's last name."
    },
        "height": {
      "type": "integer",
      "description": "The person's height in cm."
    },
    "age": {
      "description": "Age in years which must be equal to or greater than zero.",
      "type": "integer",
      "minimum": 0
    },
        "home": {
      "type": "object",
      "description": "The person's home",
            "properties": {
            "address": {
              "type": "string",
              "description": "The address of their home."
            },
                "size": {
              "type": "integer",
                    "readOnly": true,
              "description": "The size of their home in square meters."
            }
          }
    }
  }
}

Zur einer Person könnte bspw. ein Objekt Haus gehören, wobei die Eigenschaft size readOnly ist und durch den Benutzer nicht verändert werden kann. In der Engine werden die Daten jedoch als JSON Objekte gespeichert. Dies bedeutet, dass sie nur als ganzes gespeichert werden können. Deshalb werden die bestehenden Daten geladen und mit den Änderungen des Benutzers zusammengefügt. Erst nach diesem Schritt können die Daten gespeichert und zusammen mit der Aufgabe abgeschlossen werden. In DigiWF haben wir hierfür eine eigene Bibliothek geschrieben, die bestimmten Funktionalitäten dafür kapselt: https://github.com/it-at-m/digiwf-core/tree/dev/digiwf-libs/digiwf-json-serialization

Fazit

In diesem Blogpost haben wir einen kurzen Einblick in die JSON Schema Technologie erhalten und Implementierungsansätze kennengelernt, wie wir diese bei der Digitalisierung von Prozessen mit Camunda nutzen können. Im nächsten Blogpost schauen wir uns einen weiteren Anwendungsfall an - JSON Schema als Datenbeschreibung eines Prozesses, um die Nutzung von wiederverwendbaren Prozessbausteinen zu vereinfachen.


Tags

#camunda#bpm#low-code
Previous Article
Wiederverwendbare Prozessbausteine
Dominik Horn

Dominik Horn

Co-Founder

Inhalte

1
Einleitung
2
Was ist JSON Schema überhaupt?
3
Validierung und Serialisierung im Backend
4
Fazit

Ähnliche Beiträge

Low-Code und BPMN - Eine Kombination mit Fallstricken?
September 19, 2023
3 min
© 2024, All Rights Reserved.

Links

StartseiteLösungenBPM TrainingKarriereInsights

Social Media