Vues et styles

Le modèle décrit ce qui existe ; les vues décident de ce qu’on montre. C’est dans ce bloc que se joue la lisibilité, et c’est celui qu’on retouche le plus souvent.

Les sept types de vues

VuePortéeCorrespond à
systemLandscapePlusieurs systèmesLe paysage d’ensemble
systemContext <système>Un système et ses voisinsNiveau 1
container <système>Les conteneurs d’un systèmeNiveau 2
component <conteneur>Les composants d’un conteneurNiveau 3
dynamic <portée>Une séquence d’interactions numérotéesDiagramme dynamique
deployment <portée> <environnement>Les instances sur l’infrastructureDiagramme de déploiement
filtered <vue de base>Une vue existante, filtrée par étiquettesVariante thématique

Chaque vue accepte une clé — son identifiant, utilisé pour les noms de fichiers exportés — et une description :

views {
    systemContext billetterie "Contexte" "Qui utilise la billetterie" {
        include *
        autolayout lr
    }
}
Tip

Donnez toujours une clé explicite. Sans elle, Structurizr en génère une — SystemContext-001 — qui change dès qu’on réordonne les vues, ce qui fait bouger tous les noms de fichiers exportés et pollue chaque diff.

La vue dynamique

La seule qui décrive un scénario plutôt qu’une structure. Les relations sont énumérées dans l’ordre, et Structurizr les numérote.

dynamic billetterie "Reservation" "Le parcours de réservation" {
    client -> billetterie.web "Choisit des places"
    billetterie.web -> billetterie.api "POST /reservations"
    billetterie.api -> billetterie.db "Verrouille les places"
    billetterie.api -> paiement "Demande l'autorisation"
    paiement -> billetterie.api "Confirme"
    billetterie.api -> billetterie.db "Valide la réservation"
    autolayout lr
}

Les relations employées doivent exister dans le modèle : la vue dynamique ne peut pas inventer un échange. C’est une contrainte utile, qui empêche de documenter un scénario impossible.

Une portée peut aussi être un conteneur — pour montrer une séquence entre composants — ou * pour un scénario inter-systèmes.

Choisir ce qu’on affiche

include et exclude acceptent des expressions, et c’est le vrai levier de lisibilité sur un gros modèle.

ExpressionSélectionne
*Tout ce qui est pertinent pour la portée de la vue
<identifiant>Un élément précis
element.tag==ExterneLes éléments portant l’étiquette
element.tag!=DépréciéCeux qui ne la portent pas
element.tag==Externe,SaaSCeux qui portent les deux étiquettes
element.type==ContainerPar type
element.parent==billetterieLes enfants d’un élément
element.technology==PostgreSQLPar technologie
->billetterie.api->L’API, plus tout ce qui entre et sort
billetterie.api->L’API et ce qu’elle appelle
->billetterie.apiL’API et ce qui l’appelle
relationship.tag==AsynchroneLes relations étiquetées

Le motif le plus utile en pratique est include * suivi d’exclude ciblés :

container billetterie "Conteneurs" {
    include *
    exclude "element.tag==Déprécié"        // Masquer le legacy en cours de retrait
    exclude "relationship.tag==Supervision" // Masquer le bruit d'observabilité
    autolayout lr
}

Et pour isoler le voisinage d’un élément, ce qui rend lisible une vue autrement saturée :

container billetterie "AutourDeLApi" "Ce qui touche à l'API" {
    include "->billetterie.api->"
    autolayout lr
}

Les vues filtrées

Une filtered dérive d’une vue existante en ne gardant — ou en retirant — que certaines étiquettes. Utile pour produire deux versions d’un même diagramme sans dupliquer sa définition.

container billetterie "Conteneurs" {
    include *
    autolayout lr
}

filtered "Conteneurs" exclude "Externe" "SansTiers" "Sans les systèmes tiers"
filtered "Conteneurs" include "Cible" "Cible" "Architecture cible uniquement"

C’est le mécanisme qui permet de documenter une trajectoire : étiqueter les éléments Actuel et Cible, et produire deux vues du même modèle.

La mise en page

autolayout délègue le placement à Graphviz.

autolayout lr 300 300

Le premier argument est la direction — tb de haut en bas, bt, lr de gauche à droite, rl — les deux suivants l’espacement entre rangs et entre nœuds, en pixels. lr convient mieux aux vues de contexte et de conteneurs, tb aux composants.

Warning

La mise en page automatique est le principal point de friction de Structurizr. Sur un diagramme de plus d’une quinzaine d’éléments, le résultat est souvent médiocre — croisements, éléments éloignés sans raison — et il n’existe pas de bon réglage.

Trois réponses, dans cet ordre. Réduire le nombre d’éléments de la vue avec les expressions ci-dessus : c’est presque toujours la vraie solution, un diagramme illisible est d’abord un diagramme trop chargé. Changer la direction, qui suffit étonnamment souvent. Placer à la main en dernier recours : retirer autolayout, positionner les éléments dans Lite ou dans la version hébergée, et laisser l’outil enregistrer les coordonnées. C’est efficace mais fragile — les positions vivent alors en dehors du DSL, et un élément ajouté ne trouve pas sa place tout seul.

Les styles

Les styles s’appliquent par étiquette, jamais par élément. C’est ce qui les rend réutilisables : on décrit une convention visuelle, pas une décoration.

views {
    styles {
        element "Element" {
            shape roundedBox
            background #1168bd
            color #ffffff
            fontSize 22
        }

        element "Person" {
            shape person
            background #08427b
        }

        element "Base de données" {
            shape cylinder
        }

        element "Externe" {
            background #999999
            color #ffffff
        }

        element "Déprécié" {
            background #cc0000
            border dashed
            opacity 60
        }

        relationship "Relationship" {
            thickness 2
            routing orthogonal
            fontSize 18
        }

        relationship "Asynchrone" {
            style dashed
        }
    }
}

Les styles se cumulent dans l’ordre de déclaration : un conteneur étiqueté Externe reçoit d’abord le style Element, puis Container, puis Externe. Il faut donc déclarer du plus général au plus spécifique.

Les propriétés disponibles

Élément
shapeForme — voir ci-dessous
iconURL ou fichier d’icône
background, color, strokeCouleurs, en hexadécimal
strokeWidthÉpaisseur du contour
bordersolid, dashed, dotted
opacity0 à 100
fontSize, width, heightDimensions
metadata, descriptiontrue ou false — affiche ou masque ces lignes
Relation
thicknessÉpaisseur du trait
stylesolid, dashed, dotted
routingdirect, orthogonal, curved
color, fontSize, width, opacity
position0 à 100 — où placer le libellé sur la ligne

Les formes disponibles : box, roundedBox, circle, ellipse, hexagon, cylinder, pipe, person, robot, folder, webBrowser, mobileDevicePortrait, mobileDeviceLandscape, component.

Les conventions qui se sont imposées : cylinder pour une base de données, pipe pour une file de messages, webBrowser pour une application monopage, person pour un humain, robot pour un acteur automatisé.

Les thèmes

Un thème est un jeu de styles publié sous forme de JSON. Le plus simple est de partir du thème par défaut et de ne surcharger que le nécessaire.

views {
    theme default

    styles {
        element "Externe" {
            background #999999
        }
    }
}

Structurizr publie des thèmes pour les principaux fournisseurs de cloud, qui apportent les icônes officielles — précieux sur un diagramme de déploiement :

themes https://static.structurizr.com/themes/default/theme.json \
       https://static.structurizr.com/themes/amazon-web-services-2023.01.31/theme.json

Les éléments prennent alors l’icône correspondant à leur étiquette — Amazon Web Services - RDS, Amazon Web Services - Elastic Container Service — ce qui rend un diagramme d’infrastructure immédiatement reconnaissable.

Warning

Ces URL sont servies par le service cloud, qui ferme le 30 septembre 2026. Deux conséquences immédiates, vérifiables dès aujourd’hui :

  • un theme default fait échouer l’export de tout format qui rend les styles — Mermaid, PlantUML — avec un délai d’attente réseau de soixante secondes, avant même la fermeture du service ;
  • une chaîne d’intégration continue qui exporte des diagrammes devient dépendante d’un service tiers pour un travail purement local.

La parade est de rapatrier les thèmes : télécharger les JSON une fois et les placer dans un dossier themes/ à côté du workspace, que la commande local sert d’office depuis /usr/local/structurizr/themes/. Le plus simple reste souvent de s’en passer : un bloc styles de dix lignes couvre l’essentiel de ce qu’apporte le thème par défaut, sans dépendance réseau.

Terminologie et image de marque

Deux blocs mineurs mais appréciés des lecteurs non techniques : renommer le vocabulaire C4, et poser un logo.

views {
    terminology {
        person "Utilisateur"
        softwareSystem "Application"
        container "Brique"
        component "Module"
    }

    branding {
        logo docs/logo.png
        font "Inter" https://fonts.googleapis.com/css2?family=Inter
    }
}

Le renommage est à manier avec précaution : il facilite la lecture pour un public non familier de C4, et il rend en revanche les diagrammes moins transposables d’un projet à l’autre.

Un bloc views complet

views {

    systemLandscape "Paysage" "L'ensemble du système d'information" {
        include *
        autolayout tb
    }

    systemContext billetterie "Contexte" {
        include *
        autolayout lr
    }

    container billetterie "Conteneurs" {
        include *
        exclude "element.tag==Déprécié"
        autolayout lr
    }

    component billetterie.api "ComposantsApi" "L'intérieur de l'API" {
        include *
        autolayout tb
    }

    dynamic billetterie "Reservation" "Le parcours de réservation" {
        client -> billetterie.web "Choisit des places"
        billetterie.web -> billetterie.api "POST /reservations"
        billetterie.api -> paiement "Demande l'autorisation"
        autolayout lr
    }

    deployment billetterie production "DeploiementProd" {
        include *
        autolayout lr
    }

    filtered "Conteneurs" exclude "Externe" "SansTiers"

    styles {
        element "Element"          { shape roundedBox background #1168bd color #ffffff }
        element "Person"           { shape person background #08427b }
        element "Base de données"  { shape cylinder }
        element "File"             { shape pipe }
        element "Externe"          { background #999999 }
        relationship "Relationship" { thickness 2 routing orthogonal }
        relationship "Asynchrone"   { style dashed }
    }

    theme default
}

Références