Skip to content

Relationships

Relationships describe the connections, data flows and interactions of the elements,
and created with the -> operator:

model {
customer = actor 'Customer'
cloud = service 'Cloud'
customer -> cloud
}

Relationships can be “kinded”:

specification {
element system
// Define relationship kind
relationship async
relationship uses
}
model {
system1 = system 'System 1'
system2 = system 'System 2'
system1 -[async]-> system2
// Or prefix with '.' to use the kind
system1 .uses system2
}

This allows us to express and add more semantics to the interactions between the elements, for instance, from a technology perspective (REST, GRPC, GraphQL, Sync/Async, etc.) or from a business perspective (delegation, inform, accountability, etc.).

It’s up to you to define the relationship kinds that make sense for your context.

Relationships may be nested

model {
actor customer
service cloud {
component backend
component frontend
frontend -> backend
customer -> frontend
}
}

Use it or this to refer parent as the source:

model {
customer = actor {
it -> frontend 'opens in browser'
this -> frontend 'opens in browser'
}
}

or to refer as the target:

model {
component frontend {
customer -> it 'opens in browser'
customer -> this 'opens in browser'
}
}

Nested relationships may be “sourceless”, then the source is the parent element

specification {
relationship graphql
}
model {
customer = actor {
// same as customer -> frontend
-> frontend 'opens in browser'
}
service cloud {
component backend
component frontend {
// same as frontend -[graphql]-> backend
-[graphql]-> backend 'requests data'
}
}
}

Relationships may have a title (and better to have one):

model {
actor customer
service cloud {
component backend
component frontend
// Title can be inlined
frontend -> backend 'requests data to display'
}
customer -> frontend {
title 'opens in browser' // or nested
}
}
model {
customer -> frontend 'opens in browser' {
technology 'HTTPS'
}
// Or in a shorter way
customer -> frontend 'opens in browser' 'HTTPS'
}
model {
customer -> frontend 'opens in browser' {
description 'Customer opens the frontend in the browser to interact with the system'
}
}

Same as for elements, you can use markdown in description with triple quotes:

model {
customer -> frontend 'opens in browser' {
description '''
**Customer** opens the frontend in the browser
to interact with the system
| checks | |
|:--------- |:-- |
| check 1 | ✅ |
| check 2 | ⛔️ |
| check 3 | ✅ |
'''
}
}

Relationships may be tagged

model {
// inlined
frontend -> backend 'requests data' #graphql #team1
// or nested
customer -> frontend 'opens in browser' {
#graphql #team1
}
}

Relationships may have multiple links:

model {
customer -> frontend 'opens in browser' {
// External link
link https://any-external-link.com
// or any URI
link ssh://bastion.internal 'SSH'
// or relative link to navigate to sources
link ../src/index.ts#L1-L10
}
}

Relationship may have a navigateTo property, which is a link to some dynamic view.
This allows to “zoom-in” and see more details about this relationship.

model {
webApp -> backend.api {
title 'requests data for the dashboard'
navigateTo dashboardRequestFlow
}
}

Same as elements metadata:

model {
customer -> frontend 'opens in browser' {
metadata {
prop1 'value1'
prop2 '
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: app-statefulset
spec: {}
'
}
}
}