Zum Inhalt

Systemübergreifende Referenzen

2024-08-19

Beteiligte

Name Abgelehnt Angenommen
Frank Gehann x
Grigorij Shelyubsky x
Felix Forbrig x
Christian Rose x
Daniel Krämer x

Status

[ Vorgeschlagen | Angenommen | Abgelehnt | Ersetzt ]

Kontext

Ziel ist es, effizient "Querverweise" / "Referenzen" zwischen Objekten unterschiedlicher Systeme / Services zu schaffen.

U.a. sind Objekte aus folgenden Services zu betrachten:

  • CoreEntities (aus Service CoreEntity)
  • Tasks (aus Service Hustleboard)
  • Chats (aus Service Chat)
  • Mails (aus externer Applikation Outlook)

Es sollen u.a. folgende Anforderungen bzgl. dem Anlegen von Referenzen erfüllbar sein:

  • "Lege einen Chat-Entity für ein Dokument (Core-Entity) an"
  • "Lege einen Task-Entity für einen Chat-Entity an"
  • "Lege einen Chat-Entity für eine E-Mail in Outlook an"
  • "Lege einen Querverweis zwischen unterschiedlichen Dokumenten (Core-Entities) an z.B. mit dem Referenz-Typ 'ist Anlage von'"
  • ...

Es sollen u.a. folgende Anforderungen bzgl. dem Abfragen von Referenzen erfüllbar sein:

  • Abfragen folgender Form sollen möglich und performant sein: "Gib alle Core-Entities unter einem Parent-Core-Entity zurück, für die es 1 Chat-Entity gibt"
  • Eine Graph-API ähnliche (OData-basierte) zentrale Abfrage über Objekte unterschiedlicher Services soll möglich sein

Es sollen u.a. folgende Anforderungen bzgl. dem Anzeigen von Referenzen erfüllbar sein:

Anzeige eines Links zu dem referenzierten Objekt im entsprechenden Service (bzw. dessen primäre UI)

  • Core-Entities -> MAVERICK Web-Client
  • Tasks--Entities -> Hustleboard
  • Chats-Entities -> Chat UI
  • (externe) Mails -> z.B. Outlook

Anzeige zusätzlicher definierter Daten des referenziertem Objektes, damit der User das Objekt "wiedererkennen" kann. Z.B.

Entscheidung

Aufbau von Object-IDs

Analog zur MavericEntityId wie sie in Core genutzt wird, sollen auch IDs aus anderen Services / Systemen (im Kontext von Referenzen) folgendes Format bekommen:

<Source>:<Type>:<Identifier>

  • Source: Eindeutiger Bezeichner des System / Service oder des Moduls in einem System / Service. Beim Anzeigen / Abfragen von Referenzen sollten diese "wohlbekannt" sein und daraufhin das Ziel-System erkennbar machen. Beispiele:

    • "clouddrive" -> Core-Service
    • "chat" -> Chat-Service
    • "task" -> Task-Service
    • "mail" -> Outlook
  • Type: Innerhalb der Source eindeutiger Bezeichner des Objekt-Typs. Falls eine Source nur 1 Objekt-Typ kennt, kann hier gerne derselbe String stehen, wie in Source. Aber die 3-Teiligkeit der Gesamt-ID muss bestehen bleiben. Beispiele:

    • "Document" -> definiert in Core-Service's "clouddrive"
    • "Folder" -> definiert in Core-Service's "clouddrive"
    • "chat" -> definiert in Chat-Service's "chat"
    • "task" -> definiert in Task-Service's "task"
    • "mail" -> definiert in Outlook's "mail"
  • Identifier: Mindestens innerhalb des "Qualified Types" <Source>:<Type> eindeutige ID des Objekts selbst.

Referenz

Eine Referenz definiert sich mindestens aus folgenden Informationen:

  • Source - Object-ID: Ein Ende einer Referenz-Kante
  • Target - Object-ID: Das andere Ende einer Referenz-Kante
  • Referenz-Typ: Der Typ der Referenz (string).
    • z.B. "Anlage", "Vorgänger"
  • Direction: Variante der Kante (Enum)
    • Unidirektional: Die Kante ist gerichtet, z.B. um "ist Anlage von" und "hat Anlage" zu unterscheiden, je nachdem, ob man von der Quelle oder dem Ziel auf die Kante schaut
    • Bidrektional: Die Kante hat in beide Richtungen dieselbe Bedeutung
  • CreatedBy: User-ID des Erstellers der referenz oder "system"
  • CreatedAt: Timestampt wann die referenz erstellt wurde
  • Comment: optionaler Kommentar zu der Referenz
  • zusätzliche Source-Eigenschaften zur Anzeige: optionales Properties Objekt (s.u.) mit Wellknown-Properties, welche weitere Informationen zur Anzeige des Quell-Objekts bereit stellt
  • zusätzliche Target-Eigenschaften zur Anzeige: optionales Properties Objekt (s.u.) mit Wellknown-Properties, welche weitere Informationen zur Anzeige der Ziel-Objekts bereit stellt

Wellknown-Properties Object

  • Title (string)
    • Beschreibung: Der Titel des referenzierten Objekts. Dies ist die primäre Bezeichnung, unter der das Objekt bekannt ist und wird in der Benutzeroberfläche prominent angezeigt.
    • Beispiel: "Title": "Projektplan Q4"
  • Description (string)
    • Beschreibung: Eine kurze Beschreibung oder Zusammenfassung des Inhalts oder der Funktion des referenzierten Objekts.
    • Beispiel: "Description": "Dokument enthält die Projektplanung für das vierte Quartal."
  • ObjectType (string)
    • Beschreibung: Der Typ des referenzierten Objekts, z.B. ob es sich um ein Dokument, eine Aufgabe, einen Chat oder eine E-Mail handelt. Dies hilft bei der schnellen Identifikation des Objekts.
    • Beispiel: "ObjectType": "Document"
  • CreatedAt (datetime)
    • Beschreibung: Das Erstellungsdatum des referenzierten Objekts. Hilft dem Nutzer, die zeitliche Einordnung des Objekts vorzunehmen.
    • Beispiel: "CreatedAt": "2024-04-22T10:15:30Z"
  • CreatedBy (string)
    • Beschreibung: Die ID oder der Name des Benutzers, der das referenzierte Objekt erstellt hat. Dies kann wichtig sein, um die Verantwortlichkeit nachzuvollziehen.
    • Beispiel: "CreatedBy": "user123"
  • LastModifiedAt (datetime, optional)
    • Beschreibung: Das Datum der letzten Änderung am referenzierten Objekt. Dies gibt Aufschluss über die Aktualität der Daten.
    • Beispiel: "LastModifiedAt": "2024-05-01T14:22:05Z"
  • Icon (string - URL oder Base64-encoded SVG)
    • Beschreibung: Ein Icon oder Bild, das das referenzierte Objekt visuell repräsentiert. Kann ein URL oder ein Base64-codiertes SVG-Bild sein.
    • Beispiel: "Icon": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI1MCIgdmlld0JveD0iMCAwIDQ4IDUwIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iNDgiIGhlaWdodD0iNTAiIGZpbGw9IiM0NDQ0NDQiLz48L3N2Zz4="
  • Link (string - URL)
    • Beschreibung: Ein direkter Link zur primären UI des referenzierten Objekts. Dies ermöglicht es dem Nutzer, das Objekt schnell zu öffnen.
    • Beispiel: "Link": "https://maverick.core.com/doc/12345"
{
    "Title": "Projektplan Q4",
    "Description": "Dokument enthält die Projektplanung für das vierte Quartal.",
    "ObjectType": "Document",
    "CreatedBy": "user123",
    "CreatedAt": "2024-04-22T10:15:30Z",
    "LastModifiedAt": "2024-05-01T14:22:05Z",
    "Icon": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OCIgaGVpZ2h0PSI1MCIgdmlld0JveD0iMCAwIDQ4IDUwIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iNDgiIGhlaWdodD0iNTAiIGZpbGw9IiM0NDQ0NDQiLz48L3N2Zz4=",
    "Link": "https://maverick.core.com/doc/12345"
}

zentraler Service

Ein zentraler Referenz-Service "verbindet" die Services.

Responsibility

Das Anlegen einer Referenz passiert immer in dem Service, der auch jetzt schon die Responsibility für den entsprechenden Referenz-Typ hat, bzw. das "Child"-Objekt stellt (Foreign Key Konzept):

  • Core: Querverweise zwischen Core-Entities
  • Chat: Referenz von Chat-Entity auf Core-Entity, Task-Entity oder externem Objekt
  • Task: Referenz von Task-Entity auf Core-Entity oder externem Objekt

Ablauf

Die zum Abfragen und Anzeigen der Referenz benötigten Informationen aus Quell- und Ziel-Service, werden dabei aus Projektionen des jeweiligen Service hinzugefügt.

Mögliches Szenario:

sequenceDiagram
    participant Source Service
    participant Target Service
    participant Message Queue
    participant Reference Service

    Source Service->>Source Service: Create Reference between Source-Obj and Target-Obj
    Source Service->>Message Queue: Create Reference (via Projection) between Source-Obj and Target-Obj incl. Source-Obj Details
    Message Queue->>Reference Service: Create Reference ...
    Reference Service->>Message Queue: Get Details
    Message Queue->>Target Service: Get Details
    Target Service->>Message Queue: Update Target-Obj Details (via Projection)
    Message Queue->>Reference Service: Update Target-Obj Details

Sobald sich Informationen in Source- oder Target-Service der jeweiligen Objekte ändern, müssen diese aktiv im Referenz-Service upgedated werden:

sequenceDiagram
    participant Source-Service
    participant Target-Service
    participant Message Queue
    participant Reference Service

    Source-Service->>Message Queue: Update Source-Obj Details (via Projection)
    Message Queue->>Reference Service: Update Source-Obj Details
    Target-Service->>Message Queue: Update Target-Obj Details (via Projection)
    Message Queue->>Reference Service: Update Target-Obj Details

Wird Source-Obj oder Target-Obj gelöscht wird, wird ebenfalls die Referenz gelöscht.

Konsequenzen

(+) Jeder Service kann wie bisher "seine" Referenzen speichern => keine Änderung der Implementierung

(+) Jeder Service kann die IDs seiner eigenen Objekte verwalten wie bisher => keine Änderung der Implementierung

(-) Zusätzliche Implementierung nötig für Projektion der Referenzen und Obj-Details. Auch Object-Ids müssen innerhalb der Projektionen dann wie oben beschrieben erstellt werden => Implementierungs-Aufwand

(-) Zusätzlicher zentraler Referenz-Service nötig

(+) Abfrage von Referenzen ist zentral möglich => performant, mit Graph-API (OData) verheiratbar und beinhaltet direkt genügend Details zur Anzeige

Alternativen

Alternatve wäre gewesen, dass die Refenz-Implementierungen in jedem Service ohne Änderung so dezentral bleiben