goadesign / model

Create your software architecture models and diagrams in Go.
MIT License
331 stars 19 forks source link

Properly render external systems in container views #690

Closed raphael closed 2 months ago

raphael commented 2 months ago

Could be related to #648

When creating a container view that contains references to external systems mdl does not properly render the external system boundary. Instead it creates separate boxes for the system and its containers.

Example DSL:

package model

import . "goa.design/model/dsl"

var _ = Design("Example", "An example with a container view containing two systems", func() {
    SoftwareSystem("SystemA", "System A", func() {
        Container("ContainerA", "Container A", "Does something", func() {
            Uses("SystemB/ContainerB", "Uses")
        })
    })

    SoftwareSystem("SystemB", "System B", func() {
        Container("ContainerB", "Container B", "Does something", func() {
            Uses("ContainerC", "Uses")
        })
        Container("ContainerC", "Container C", "Does something", func() {
        })
    })

    Views(func() {
        ContainerView("SystemA", "Container view", func() {
            AddAll()
            Add("SystemB/ContainerB")
            Add("SystemB/ContainerC")
        })
    })
})

Rendered diagram:

Screenshot 2024-04-29 at 1 30 39 PM

As comparison here is a similar situation in structurizr DSL:

workspace {
    model {
        user = person "User"
        softwareSystem = softwareSystem "Software System" {
            webapp = container "Web Application" {
                user -> this "Uses"
            }
            container "Database" {
                webapp -> this "Reads from and writes to"
            }
        }
        softwareSystem2 = softwareSystem "Software System 2" {
            webapp2 = container "Web Application 2" {
                user -> this "Uses"
            }
            webapp3 = container "Web Application 3" {
                webapp2 -> this "Uses"
            }
            container "Database 2" {
                webapp2 -> this "Reads from and writes to"
            }
        }
    }
    views {
        container softwareSystem {
            include *
            include webapp2
            include webapp3
            autolayout lr
        }
        theme default
    }
}

And the diagram:

Screenshot 2024-04-29 at 1 32 10 PM

cc @dvictor

raphael commented 2 months ago

For reference here is the JSON produced by mdl in the example above:

{
    "name": "Example",
    "description": "An example with a container view containing two systems",
    "model": {
        "softwareSystems": [
            {
                "id": "sudetj",
                "name": "SystemA",
                "description": "System A",
                "tags": "Element,Software System",
                "containers": [
                    {
                        "id": "1l2fgho",
                        "name": "ContainerA",
                        "description": "Container A",
                        "technology": "Does something",
                        "tags": "Element,Container",
                        "relationships": [
                            {
                                "id": "5rfsov",
                                "description": "Uses",
                                "tags": "Relationship",
                                "sourceId": "1l2fgho",
                                "destinationId": "vj0iw4",
                                "interactionStyle": "Undefined"
                            }
                        ]
                    }
                ]
            },
            {
                "id": "t4d0ii",
                "name": "SystemB",
                "description": "System B",
                "tags": "Element,Software System",
                "containers": [
                    {
                        "id": "vj0iw4",
                        "name": "ContainerB",
                        "description": "Container B",
                        "technology": "Does something",
                        "tags": "Element,Container",
                        "relationships": [
                            {
                                "id": "43dr89",
                                "description": "Uses",
                                "tags": "Relationship",
                                "sourceId": "vj0iw4",
                                "destinationId": "vt04l3",
                                "interactionStyle": "Undefined"
                            }
                        ]
                    },
                    {
                        "id": "vt04l3",
                        "name": "ContainerC",
                        "description": "Container C",
                        "technology": "Does something",
                        "tags": "Element,Container"
                    }
                ]
            }
        ]
    },
    "views": {
        "containerViews": [
            {
                "key": "Container view",
                "order": 0,
                "elements": [
                    {
                        "id": "1l2fgho"
                    },
                    {
                        "id": "t4d0ii"
                    },
                    {
                        "id": "vj0iw4"
                    },
                    {
                        "id": "vt04l3"
                    }
                ],
                "relationships": [
                    {
                        "id": "43dr89",
                        "description": "Uses"
                    },
                    {
                        "id": "5rfsov",
                        "description": "Uses"
                    }
                ],
                "softwareSystemId": "sudetj"
            }
        ]
    }
}