plantuml-stdlib / C4-PlantUML

C4-PlantUML combines the benefits of PlantUML and the C4 model for providing a simple way of describing and communicate software architectures

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Missing relationship documentation

rcavaz opened this issue · comments

There is no documentation describing the behavior of the Rel_Back and Rel_Neighbor relationships.

These relationships are shown as part of some of the examples but their behavior is unclear.

Hi @rcavaz,

  • Rel_Neighbor:
    neighbor elements are logical on the same "level" and should not introduce an additional "level" between the elements.
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

System_Boundary(c1, "Internet Banking") {
    Container(mobile_app, "Mobile App", "C#, Xamarin")

    Container(main_backend_api, "Main API", "Java, Docker Container")
    Container(other1_backend_api, "Other1 API", "Java, Docker Container")
    Container(other2_backend_api, "Other2 API", "Java, Docker Container")

    ContainerDb(main_db, "Main DB", "MySql, Docker Container")
    ContainerDb(other1_db, "Other1 DB", "MySql, Docker Container")
    ContainerDb(other2_db, "Other2 DB", "MySql, Docker Container")
}

Rel(mobile_app, main_backend_api, "Uses")
Rel_Neighbor(main_backend_api, other1_backend_api, "Uses")
Rel_Neighbor(main_backend_api, other2_backend_api, "Uses")

Rel(main_backend_api, main_db, "Stores")
Rel(other1_backend_api, other1_db, "Stores")
Rel(other2_backend_api, other2_db, "Stores")

SHOW_LEGEND()
@enduml

If you remove _Neighbor like in following sample you should see the difference.

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

System_Boundary(c1, "Internet Banking") {
    Container(mobile_app, "Mobile App", "C#, Xamarin")

    Container(main_backend_api, "Main API", "Java, Docker Container")
    Container(other1_backend_api, "Other1 API", "Java, Docker Container")
    Container(other2_backend_api, "Other2 API", "Java, Docker Container")

    ContainerDb(main_db, "Main DB", "MySql, Docker Container")
    ContainerDb(other1_db, "Other1 DB", "MySql, Docker Container")
    ContainerDb(other2_db, "Other2 DB", "MySql, Docker Container")
}

Rel(mobile_app, main_backend_api, "Uses")
' remove _Neighbor add level
Rel(main_backend_api, other1_backend_api, "Uses")
Rel(main_backend_api, other2_backend_api, "Uses")

Rel(main_backend_api, main_db, "Stores")
Rel(other1_backend_api, other1_db, "Stores")
Rel(other2_backend_api, other2_db, "Stores")

' add Lay_Neighbor that all dbs are on the same level again
' ups... this call is missing, but it can be simulated
' Lay_Neighbor(other2_backend_api, main_db)
Lay_Distance(other2_backend_api, main_db, 0)

SHOW_LEGEND()
@enduml

  • Rel_Back:
    back relationships model a logical response back from a target to the source,
    e.g. like an observer pattern
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

' only that it is more visible
AddRelTag("back (after register)", $textColor = $ARROW_COLOR, $lineColor = $ARROW_COLOR, $lineStyle = DashedLine())

System_Boundary(c1, "Earth Weather") {
    Container(backend_api, "Meteorological Station API", "Java, Docker Container")
    Container(mobile_app2, "Mobile Weather App2", "C#, Xamarin")
    Container(mobile_app, "Mobile Weather App", "C#, Xamarin")
    ContainerDb(weather_archive, "Weather Archive", "MySql, Docker Container")
}

Rel(mobile_app, backend_api, "register")
Rel_Back(mobile_app, backend_api, "send weather data update", $tags="back (after register)")

' based on Rel_Back the logic is known that mobile_app2 initiated the connection
' Rel(mobile_app2, backend_api, "register")
Rel_Back(mobile_app2, backend_api, "send weather data update", $tags="back (after register)")

' with Rel() it would create a complete different logic/layout 
Rel(backend_api, weather_archive, "send weather data update", $descr = "but weather_archive is not specified via register call,\nits specified via e.g. config in backend_api")

SHOW_LEGEND()
@enduml

I hope it helps

BR Helmut