Dieser Post baut auf dem achtundzwanzigsten Teil auf. Alle bisherigen Beispiele im Tutorial zeigten fiktive Systeme. Hier kommt ein echtes Referenzmodell: das Big Bank Example von Simon Brown — dem Erfinder des C4-Modells und Hauptentwickler von Structurizr.

Und zum ersten Mal wird es nicht von Hand geschrieben, sondern direkt aus Structurizr DSL importiert.

bausteinsicht import --from structurizr ist ab dem Release nach v1.1.0 verfügbar (gemergt in PR #331). Mit der aktuell installierten v1.1.0 funktioniert der Befehl noch nicht — wer es schon jetzt ausprobieren will, baut Bausteinsicht lokal aus main.

Was ist das Big Bank Example?

Das Big Bank Example ist das offizielle Referenzmodell der Structurizr-Dokumentation. Es zeigt eine fiktive Retail-Bank mit einem Internet Banking System auf drei C4-Ebenen:

  • System Context — Kunden, Bankmitarbeiter, ATM, externe Systeme

  • Container — Web App, SPA, Mobile App, API Application, Oracle-Datenbank

  • Component — Sechs Komponenten der API Application

Das Modell ist komplex genug um alle Features von Bausteinsicht zu zeigen, und bekannt genug um es sofort einordnen zu können.

Voraussetzungen

# Bausteinsicht aus main (solange v1.2.0 noch nicht released):
go install github.com/docToolchain/Bausteinsicht/cmd/bausteinsicht@main

# Oder bei installiertem Node.js:
npm install -g @doctoolchain/bausteinsicht@next

Ein leeres Verzeichnis für das Experiment:

mkdir bigbank && cd bigbank

Schritt 1: DSL herunterladen

Das kombinierte Big Bank DSL (System Landscape + Internet Banking System) direkt von Structurizr holen:

curl -o bigbank.dsl https://structurizr.connectedpdf.com/share/3/dsl
workspace "Big Bank plc" "This is an example workspace..." {
  model {
    customer = person "Personal Banking Customer" "..."

    enterprise "Big Bank plc" {
      supportStaff = person "Customer Service Staff" "..."
      backoffice   = person "Back Office Staff"      "..."

      mainframe = softwaresystem "Mainframe Banking System" "..." "Existing System"
      email     = softwaresystem "E-mail System"            "..." "Existing System"
      atm       = softwaresystem "ATM"                      "..." "Existing System"

      internetBankingSystem = softwaresystem "Internet Banking System" "..." {
        webApplication = container "Web Application"        "..." "Java and Spring MVC"
        spa            = container "Single-Page Application" "..." "JavaScript and Angular"
        mobileApp      = container "Mobile App"             "..." "Xamarin"
        apiApplication = container "API Application"        "..." "Java and Spring MVC" {
          signinController           = component "Sign In Controller"             "..." "Spring MVC"
          accountsSummaryController  = component "Accounts Summary Controller"    "..." "Spring MVC"
          resetPasswordController    = component "Reset Password Controller"      "..." "Spring MVC"
          securityComponent          = component "Security Component"             "..." "Spring Bean"
          mainframeBankingSystemFacade = component "Mainframe Banking System Facade" "..." "Spring Bean"
          emailComponent             = component "E-mail Component"               "..." "Spring Bean"
        }
        database = container "Database" "..." "Oracle Database Schema"
      }
    }

    customer -> internetBankingSystem "Views account balances, and makes payments using"
    customer -> supportStaff "Asks questions to" "Telephone"
    customer -> atm "Withdraws cash using"
    ...
  }
}

Schritt 2: Vorschau mit --dry-run

Bevor eine Datei geschrieben wird, den Import als Vorschau ausführen:

bausteinsicht import --from structurizr bigbank.dsl --dry-run

Der Befehl gibt das generierte JSONC auf stdout aus — ohne etwas zu schreiben. So lässt sich prüfen ob das Parsing korrekt ist, bevor man eine vorhandene architecture.jsonc überschreibt.

{
  "$schema": "https://raw.githubusercontent.com/docToolchain/Bausteinsicht/main/schemas/bausteinsicht.schema.json",
  "specification": {
    "elements": {
      "person":    { "notation": "Person" },
      "system":    { "notation": "Software System", "container": true },
      "container": { "notation": "Container",       "container": true },
      "component": { "notation": "Component",       "container": true }
    },
    "relationships": {
      "uses": { "notation": "uses" }
    },
    "tags": [
      { "id": "existing-system" },
      { "id": "bank-staff" },
      { "id": "web-browser" },
      { "id": "mobile-app" },
      { "id": "database" }
    ]
  },
  "model": { ... },
  "relationships": [ ... ],
  "views": { ... }
}

Falls das Parsing eines bestimmten DSL-Konstrukts nicht unterstützt wird, gibt bausteinsicht import eine Warnung auf stderr aus — der Import läuft aber weiter durch. Deployment-Diagramme (deploymentEnvironment) werden übersprungen und als Warnung gemeldet.

Schritt 3: Import ausführen

bausteinsicht import --from structurizr bigbank.dsl

Ergebnis:

✓ Parsed 3 persons, 4 systems, 5 containers, 6 components
✓ Resolved 25 relationships
⚠ Skipped: deploymentEnvironment "Development" (not supported)
⚠ Skipped: deploymentEnvironment "Live" (not supported)
✓ Written architecture.jsonc

architecture.jsonc liegt jetzt im Verzeichnis. Das generierte File für das Big Bank Example siehst du hier:

{
  // Teil 29: Big Bank Example — transformiert von Structurizr DSL nach Bausteinsicht JSONC
  // Original DSL: https://structurizr.connectedpdf.com/share/3/dsl
  // Quelle: Simon Brown, Big Bank plc (kombiniert aus workspace 28201 + 36141)
  "$schema": "https://raw.githubusercontent.com/docToolchain/Bausteinsicht/main/schemas/bausteinsicht.schema.json",
  "config": {
    "author": "Simon Brown (Original), Paul Fleischmann (Bausteinsicht-Transformation)",
    "metadata": true,
    "legend": true
  },
  "specification": {
    "elements": {
      "actor":     { "notation": "Person" },
      "system":    { "notation": "Software System", "container": true },
      "container": { "notation": "Container",        "container": true },
      "component": { "notation": "Component",        "container": true }
    },
    "relationships": {
      "uses":  { "notation": "uses" },
      "sends": { "notation": "sends", "dashed": true }
    },
    "tags": [
      {
        "id": "external",
        "description": "Existing System — nicht unter unserer Kontrolle",
        "style": { "fillColor": "#999999", "fontColor": "#ffffff" }
      },
      {
        "id": "bank-staff",
        "description": "Bankmitarbeiter (intern)",
        "style": { "fillColor": "#08427b", "fontColor": "#ffffff" }
      },
      {
        "id": "web-browser",
        "description": "Läuft im Web-Browser des Kunden"
      },
      {
        "id": "mobile",
        "description": "Läuft auf dem Mobilgerät des Kunden"
      },
      {
        "id": "database",
        "description": "Datenbank"
      }
    ]
  },
  "model": {
    // ── Personen ─────────────────────────────────────────────────────────────
    "customer": {
      "kind": "actor",
      "title": "Personal Banking Customer",
      "description": "A customer of the bank, with personal bank accounts."
    },
    "support-staff": {
      "kind": "actor",
      "title": "Customer Service Staff",
      "description": "Customer service staff within the bank.",
      "tags": ["bank-staff"]
    },
    "backoffice": {
      "kind": "actor",
      "title": "Back Office Staff",
      "description": "Administration and support staff within the bank.",
      "tags": ["bank-staff"]
    },

    // ── Externe Systeme ───────────────────────────────────────────────────────
    "mainframe": {
      "kind": "system",
      "title": "Mainframe Banking System",
      "description": "Stores all of the core banking information about customers, accounts, transactions, etc.",
      "tags": ["external"]
    },
    "email": {
      "kind": "system",
      "title": "E-mail System",
      "description": "The internal Microsoft Exchange e-mail system.",
      "tags": ["external"]
    },
    "atm": {
      "kind": "system",
      "title": "ATM",
      "description": "Allows customers to withdraw cash.",
      "tags": ["external"]
    },

    // ── Internet Banking System (intern, mit Containern) ──────────────────────
    "internet-banking": {
      "kind": "system",
      "title": "Internet Banking System",
      "description": "Allows customers to view information about their bank accounts, and make payments.",
      "status": "deployed",
      "children": {
        "web-app": {
          "kind": "container",
          "title": "Web Application",
          "technology": "Java and Spring MVC",
          "description": "Delivers the static content and the Internet banking single page application.",
          "status": "deployed"
        },
        "spa": {
          "kind": "container",
          "title": "Single-Page Application",
          "technology": "JavaScript and Angular",
          "description": "Provides all of the Internet banking functionality to customers via their web browser.",
          "status": "deployed",
          "tags": ["web-browser"]
        },
        "mobile-app": {
          "kind": "container",
          "title": "Mobile App",
          "technology": "Xamarin",
          "description": "Provides a limited subset of the Internet banking functionality to customers via their mobile device.",
          "status": "deployed",
          "tags": ["mobile"]
        },
        "api-app": {
          "kind": "container",
          "title": "API Application",
          "technology": "Java and Spring MVC",
          "description": "Provides Internet banking functionality via a JSON/HTTPS API.",
          "status": "deployed",
          "children": {
            "sign-in": {
              "kind": "component",
              "title": "Sign In Controller",
              "technology": "Spring MVC Rest Controller",
              "description": "Allows users to sign in to the Internet Banking System."
            },
            "accounts-summary": {
              "kind": "component",
              "title": "Accounts Summary Controller",
              "technology": "Spring MVC Rest Controller",
              "description": "Provides customers with a summary of their bank accounts."
            },
            "reset-password": {
              "kind": "component",
              "title": "Reset Password Controller",
              "technology": "Spring MVC Rest Controller",
              "description": "Allows users to reset their passwords with a single use URL."
            },
            "security": {
              "kind": "component",
              "title": "Security Component",
              "technology": "Spring Bean",
              "description": "Provides functionality related to signing in, changing passwords, etc."
            },
            "mainframe-facade": {
              "kind": "component",
              "title": "Mainframe Banking System Facade",
              "technology": "Spring Bean",
              "description": "A facade onto the mainframe banking system."
            },
            "email-component": {
              "kind": "component",
              "title": "E-mail Component",
              "technology": "Spring Bean",
              "description": "Sends e-mails to users."
            }
          }
        },
        "database": {
          "kind": "container",
          "title": "Database",
          "technology": "Oracle Database Schema",
          "description": "Stores user registration information, hashed authentication credentials, access logs, etc.",
          "status": "deployed",
          "tags": ["database"]
        }
      }
    }
  },

  "relationships": [
    // ── System Context ────────────────────────────────────────────────────────
    { "from": "customer",       "to": "internet-banking", "label": "views account balances, and makes payments using",  "kind": "uses" },
    { "from": "customer",       "to": "support-staff",    "label": "asks questions to",       "kind": "uses" },
    { "from": "customer",       "to": "atm",              "label": "withdraws cash using",     "kind": "uses" },
    { "from": "support-staff",  "to": "mainframe",        "label": "uses",                     "kind": "uses" },
    { "from": "backoffice",     "to": "mainframe",        "label": "uses",                     "kind": "uses" },
    { "from": "atm",            "to": "mainframe",        "label": "uses",                     "kind": "uses" },
    { "from": "internet-banking", "to": "mainframe",      "label": "gets account information from, and makes payments using", "kind": "uses" },
    { "from": "internet-banking", "to": "email",          "label": "sends e-mail using",       "kind": "sends" },
    { "from": "email",          "to": "customer",         "label": "sends e-mails to",         "kind": "sends" },

    // ── Container: Customer → Frontend ────────────────────────────────────────
    { "from": "customer",                  "to": "internet-banking.web-app",    "label": "visits bigbank.com/ib using [HTTPS]",                             "kind": "uses" },
    { "from": "customer",                  "to": "internet-banking.spa",        "label": "views account balances, and makes payments using",                "kind": "uses" },
    { "from": "customer",                  "to": "internet-banking.mobile-app", "label": "views account balances, and makes payments using",                "kind": "uses" },
    { "from": "internet-banking.web-app",  "to": "internet-banking.spa",        "label": "delivers to the customer's web browser",                         "kind": "uses" },

    // ── Container: Frontend → Components ─────────────────────────────────────
    { "from": "internet-banking.spa",        "to": "internet-banking.api-app.sign-in",        "label": "makes API calls to [JSON/HTTPS]", "kind": "uses" },
    { "from": "internet-banking.spa",        "to": "internet-banking.api-app.accounts-summary","label": "makes API calls to [JSON/HTTPS]", "kind": "uses" },
    { "from": "internet-banking.spa",        "to": "internet-banking.api-app.reset-password",  "label": "makes API calls to [JSON/HTTPS]", "kind": "uses" },
    { "from": "internet-banking.mobile-app", "to": "internet-banking.api-app.sign-in",         "label": "makes API calls to [JSON/HTTPS]", "kind": "uses" },
    { "from": "internet-banking.mobile-app", "to": "internet-banking.api-app.accounts-summary","label": "makes API calls to [JSON/HTTPS]", "kind": "uses" },
    { "from": "internet-banking.mobile-app", "to": "internet-banking.api-app.reset-password",  "label": "makes API calls to [JSON/HTTPS]", "kind": "uses" },

    // ── Component: intern ─────────────────────────────────────────────────────
    { "from": "internet-banking.api-app.sign-in",        "to": "internet-banking.api-app.security",        "label": "uses", "kind": "uses" },
    { "from": "internet-banking.api-app.accounts-summary","to": "internet-banking.api-app.mainframe-facade","label": "uses", "kind": "uses" },
    { "from": "internet-banking.api-app.reset-password",  "to": "internet-banking.api-app.security",        "label": "uses", "kind": "uses" },
    { "from": "internet-banking.api-app.reset-password",  "to": "internet-banking.api-app.email-component", "label": "uses", "kind": "uses" },
    { "from": "internet-banking.api-app.security",        "to": "internet-banking.database",                "label": "reads from and writes to [JDBC]",  "kind": "uses" },
    { "from": "internet-banking.api-app.mainframe-facade","to": "mainframe",                                "label": "makes API calls to [XML/HTTPS]",   "kind": "uses" },
    { "from": "internet-banking.api-app.email-component", "to": "email",                                    "label": "sends e-mail using",               "kind": "sends" }
  ],

  "views": {
    "context": {
      "title": "System Context — Big Bank plc",
      "description": "Alle Akteure und Systeme rund um das Internet Banking System",
      "include": ["customer", "support-staff", "backoffice", "internet-banking", "mainframe", "email", "atm"]
    },
    "containers": {
      "title": "Container — Internet Banking System",
      "description": "Interne Container des Internet Banking Systems und ihre Nachbarn",
      "scope": "internet-banking",
      "include": ["customer", "internet-banking.*", "mainframe", "email"]
    },
    "components": {
      "title": "Component — API Application",
      "description": "Interne Komponenten der API Application",
      "scope": "internet-banking.api-app",
      "include": [
        "internet-banking.spa",
        "internet-banking.mobile-app",
        "internet-banking.api-app.*",
        "internet-banking.database",
        "mainframe",
        "email"
      ]
    }
  }
}

Was der Importer automatisch macht

Hierarchie erhalten — Structurizr-Blöcke ({ }) werden zu children-Objekten in JSONC. Der vollständig gepunktete Pfad (internet-banking.api-app.sign-in) wird aus den DSL-Variablennamen abgeleitet.

Beziehungen auflösen — Structurizr erlaubt Beziehungen die vor der Element-Definition stehen (a → b). Der Importer löst alle Referenzen verzögert auf (deferred resolution) — das Ergebnis ist immer ein konsistentes JSONC.

Tags übernehmen — Structurizr-Tags ("Existing System", "Bank Staff", "Web Browser") werden 1:1 in specification.tags übernommen und an die Elemente angehängt.

Views konvertierensystemContext, container und component Views werden in Bausteinsicht-Views übersetzt. include * wird in eine explizite include-Liste aufgelöst.

Was nachzubessern ist

Der Import ist ein Einmalvorgang — kein Mapping für alles. Folgendes muss manuell ergänzt werden:

Nicht importiertWie nachrüsten

Deployment-Diagramme

Separate Views in views anlegen oder in draw.io modellieren

Styles / Themes

specification.tags[].style mit draw.io-Farben befüllen

!include-Direktiven

Lokale Includes werden aufgelöst, HTTP-Includes nicht

properties auf Containern

metadata-Feld in Bausteinsicht verwenden

Differenzierte Beziehungstypen

Alle Beziehungen werden als uses importiert — sends, reads etc. manuell anpassen

Das Wichtigste bei externen Systemen: Structurizr nutzt den String-Tag "Existing System". Der Importer übernimmt das als Tag existing-system. Für farbiges Styling in draw.io fügt man in specification.tags einfach eine style-Sektion ein:

"specification": {
  "tags": [
    {
      "id": "existing-system",
      "description": "Externes System — nicht unter unserer Kontrolle",
      "style": { "fillColor": "#999999", "fontColor": "#ffffff" }
    }
  ]
}

Schritt 4: Sync und Diagramme

bausteinsicht sync

Bausteinsicht generiert architecture.drawio mit drei Tabs:

  • context — System Context: Kunden, Bankmitarbeiter, ATM, externe Systeme

  • containers — Alle Container des Internet Banking Systems

  • components — Sechs Komponenten der API Application

Das draw.io-File dafür findest du hier: teil_29.drawio

Generierte PNG-Dateien:

components
containers
context

Generierte PlantUML-Diagramme:

Diagram
Diagram
Diagram

Structurizr vs. Bausteinsicht — Kurzvergleich

AspektStructurizrBausteinsicht

Modell-Format

Eigene DSL

JSONC

Diagramm-Output

SVG via Structurizr-Server

draw.io (bearbeitbar, bidirektional)

Bidirektional

Nein — DSL ist Quelle der Wahrheit

Ja — draw.io Änderungen fließen zurück ins JSONC

Offline

Structurizr Lite nötig

Vollständig lokal

Deployment-Diagramme

Nativ in DSL

Kein eingebautes Konzept

Import aus Structurizr

bausteinsicht import --from structurizr

Constraint-Prüfung

!rules in DSL

constraints im JSONC, bausteinsicht lint

Die Migration in eine Richtung ist mit bausteinsicht import jetzt trivial. Zurück nach Structurizr gibt es keinen Importer — aber das ist in der Praxis selten nötig.

Was als nächstes kommt

Die wichtigsten Einstiegspunkte zum Nachschlagen:

Offizielle Dokumentation: User Manual · Tutorial auf doctoolchain.org