Coder Social home page Coder Social logo

structurizr / dsl Goto Github PK

View Code? Open in Web Editor NEW
1.4K 23.0 268.0 2.9 MB

Structurizr DSL

Home Page: https://docs.structurizr.com/dsl

License: Apache License 2.0

Java 91.47% ASL 8.49% Groovy 0.02% JavaScript 0.01% Kotlin 0.01% Ruby 0.01% Mermaid 0.01%
c4model structurizr software-architecture dsl architecture-diagrams

dsl's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dsl's Issues

Predefined tags of elements not described in the language reference

According to the documentation in Language reference, the element styles are defined using tags as identifiers (see element style). Although this is true, in my opinion documentation should specify that elements have predefined tags (e.g. Element and Person for persons).

I can create a pull request to add this information if you think it can improve the documentation.

Background color deployment node is not set

I'm trying to give a tagged deployment node a specific color/icon. The definition of the deployment node is as follows:

hermesNode = deploymentNode "Hermes Instance" "Instance of Hermes" "Docker Container" "DOCKER" {
    deploymentNode "OpenJDK 11" "" "OpenJDK 11" "JAVA" {
        containerInstance hermes
    }
}

The definition of the tag is as follows:

            element "DOCKER" {
                icon images/docker.png
                background #007bff
            }

When i look at the generated image for the deployment the tagged deployment node has no color while the icon is there.

Screen Shot 2020-09-30 at 1 17 09 PM

Relationships to/from instances not working

The documentation describes that relations

  • from Software System Instance to Infrastructure Node, Software System Instance, Container Instance
  • from Container Instance to Infrastructure Node, Software System Instance, Container Instance

are allowed. However, when creating any relation between ContainerInstance or SoftwareSystemInstance to one of the other elemens listed as valid, I get an error message that the relation is not allowed.

At a first glance the problem seems to be burried in AbstractRelationshipParser.java which IMHO doesn't include if conditions to allow the relations listed above.

Example:

workspace "Getting Started" "This is a model of my software system." {

    model {
        ss1 = softwareSystem "Software System" "My software system." {
            cont1 = container "Container" "Container"
        }
        
        ss2 = softwareSystem "Software System 2" ""

        
        deploymentEnvironment "deploytest" {
            deploymentNode wrapper "Wrapper" "Wrapper" {
                ssinstance = softwareSystemInstance ss2
                
            }
            deploymentNode wrapper2 "Wrapper2" "Wrapper" {
                continst = containerInstance cont1
                continst -> ssinstance "connects" ""
            }
        }
    }
    views {
        deployment * deploytest deploytest "test" {
            include *
        }
    }
}

Error Message:
A relationship between "ContainerInstance://deploytest/wrapper2/Software System.Container[1]" and "SoftwareSystemInstance://deploytest/wrapper/Software System 2[1]" is not permitted at line 22: continst -> ssinstance "connects" ""

Hide a relationship in a view

I have a system with slightly different component based on the deployed configuration.
Depending on the configuration certain component may lose responsibilities that I want to illustrate with relationship.
Is it possible to exclude a relationship from a view?

workspace  {

    model {
        mySystem = softwareSystem "My system" {
            componentA = container "A"
            componentB = container "B"
        }
        
        otherSystem = softwareSystem "The other system"
        
        componentA -> componentB "Do it for me"
        componentB -> otherSystem "Do it"
        componentA -> otherSystem "No B i'll do it myself"
    }

    views {
        container mySystem "ConfigurationA" {
            include *
            # Error The element/relationship "->" does not exist at line 20: exclude componentA -> otherSystem
            # exclude componentA -> otherSystem
            autoLayout
        }
        
        container mySystem "ConfigurationB" {
            include *
            exclude componentB
            autoLayout
        }
    }
}

Visual Studio Code support

Hi there, I got the DSL example to work in less than 5 mins, thanks for having documented it so well! How about "IDE" support for it, for instance Visual Studio Code? Apologies if I missed the instructions about it...

C4 does qualify as a mighty method in Michael Keeling terms :-)

Not able to add component in dynamic view

I'm trying to create a dynamic view for a flow within my system. The definition of the software system is as follows:

BulkIngestion = softwareSystem "Bulk Ingestion" "Responsible for ingesting Products defined via xml" {
    ftpServer = container "FtpServer" "FtpServer"
    disk = container "Disk" "Storage on which Product is temporary stored" "SD" "STORAGE"
    agent = container "Agent" "Triggers ingestion process when product received"
    queue = container "Ingestion Queue" "Queue of pending Product ingestions" "Redis" "QUEUE"
    worker = container "Worker" "Worker" ""Ingests uploaded Products" "Ruby"

    user -> ftpServer "Uses"
    ftpServer -> disk "Write Product"
    disk -> agent "Read"
    agent -> queue "Trigger Ingestion Product"
    worker -> queue "Consume Trigger"
    worker -> core "Create Product"
}

My dynamic view definition is as follows:

    views {
         systemLandscape "Landscape" "Landscape" {
         	include *
         	autolayout
         }

        ...

        dynamic * "IngestProduct" "Ingest Product via API" {
            User -> ftpServer "Upload Binaries Product"
        }
  }

When i try to upload my workspace i get the following exception: Caused by: com.structurizr.dsl.StructurizrDslParserException: Only people and software systems can be added to this dynamic view at line 23: User -> ftpServer "Upload Binaries Product"

Would have expected that it would be possible since dsl language spec states:

dynamic <*|software system identifier|container identifier> [key] [description] {
	...
}

Autosize diagram

Is it possible to autosize the diagrams to the size of the display?

Project not building

There are missing dependencies, when building the project with gradle, like:

import com.structurizr.documentation.AdrToolsImporter;
^
symbol: class AdrToolsImporter
location: package com.structurizr.documentation
C:\development\projects\dsl\src\main\java\com\structurizr\dsl\AdrsParser.java:39: error: cannot find symbol
AdrToolsImporter adrToolsImporter = new AdrToolsImporter(workspace, path);
^

!include with support for URLs

Are there any plans/requests to add support for URLs to the !include capabilities?

I'm modeling a rather large workspace and many of the grouped software systems themselves reside in separate repos with their own models defined as a .dsl, rather than just allowing !include to reference local relative paths, it would be nice to point them to a raw github link or something (assuming auth could be a problem here if they are not public)

there are ways we can do some of this via build scripts if needed, but it makes validating and testing the model a little more painful

Is there a reason for not having component instance in deployment environment

I'm trying to model a system at work that is effectively a system of services built on AWS components. Trying to apply the c4 model to this situations I have:

Context: The system with it's external services (for example email provider) and users
Container: Each of the containers are the individual services that consist within the system (e.g. user management, sign in, asset)
Component: Each container is then broken down into it's components, for example asset management consists of (user gateway (AWS API Gateway), user api Controller (AWS Lambda), service gateway (AWS API Gateway), service api controller (AWS Lambda).

I'd like to be able to create deployment views for each of those components (similar to the AWS example on the website), however, from the documentation it appears that there is only the option for creating an instance for softwaresystem and container.

Am I missing something? or am I completely using the model wrong? or would it be possible to add the ability to create a component instance within the DSL?

Thanks

Subsystems

It would be really useful to have another level between SoftwareSystem and Container. For example, a set of Containers could work in concert to provide a service to the Software System. Within a SoftwareSystem, Groups almost work like this, but you can't seem to address them to, say, exclude them from a View.

Jetbrains IDEs integration

Hello,

It would be a great productivity improvement, and may be a better adoption incentive of structurizr for the ones using Jetbrains IDEs such as IntelliJ to have an integration as for what has been done for VSCode.

What do you think about it ?

Thank you,

[question] How to change a relationship between views

What's the best way to show relationships with resources which sit behind a load balancer in a deployment view?

The relationship defined between two software systems/containers when looking at the System Landscape normally looks correct but when creating a deployment view, the relationships will appear as if they'd call the api directly, when in reality it would be behind a load balancer.

Is there a way to override these relationships somehow or is the best way to use a tag to exclude them from the deployment view and create a new relationship there?

e.g.

    model {
        springPetClinic = softwaresystem "Spring PetClinic" "Allows employees to view and manage information regarding the veterinarians, the clients, and their pets." "Spring Boot Application" {
            webApplication = container "Web Application" "Allows employees to view and manage information regarding the veterinarians, the clients, and their pets." "Java and Spring Boot"
            database = container "Database" "Stores information regarding the veterinarians, the clients, and their pets." "Relational database schema" "Database"
        }
        
        springMobileApp = softwareSystem "Spring PetClinic Mobile App" "" "iOS" {
            -> webApplication "Manage appointments"
        }
        
        client = person "client" {
            -> springMobileApp "Makes appointments"
        }

        webApplication -> database "Reads from and writes to" "JDBC/SSL"

        deploymentEnvironment "Live" {
            deploymentNode "UserDevice" "" "" "iOS" {
                softwareSystemInstance springMobileApp
            }
            deploymentNode "Amazon Web Services" "" "" "Amazon Web Services - Cloud" {
                deploymentNode "US-East-1" "" "" "Amazon Web Services - Region" {
                    route53 = infrastructureNode "Route 53" "" "" "Amazon Web Services - Route 53"
                    elb = infrastructureNode "Elastic Load Balancer" "" "" "Amazon Web Services - Elastic Load Balancing"

                    deploymentNode "Autoscaling group" "" "" "Amazon Web Services - Auto Scaling" {
                        deploymentNode "Amazon EC2" "" "" "Amazon Web Services - EC2" {
                            webApplicationInstance = containerInstance webApplication
                        }
                    }

                    deploymentNode "Amazon RDS" "" "" "Amazon Web Services - RDS" {
                        deploymentNode "MySQL" "" "" "Amazon Web Services - RDS_MySQL_instance" {
                            containerInstance database
                        }
                    }

                }
            }

            route53 -> elb "Forwards requests to" "HTTPS"
            elb -> webApplicationInstance "Forwards requests to" "HTTPS"
        }
    }
         
    views {
        deployment springPetClinic "Live" "AmazonWebServicesDeployment" {
            include *
            autolayout lr
        }
        
        systemLandscape SystemLandscape {
            include *
            autoLayout
        }
        
        systemContext springPetClinic "Spring_Pet_Clinic_Context" {
            include *
            autoLayout
        }

        styles {
            element "Element" {
                shape roundedbox
                background "#ffffff"
            }
            element "Database" {
                shape cylinder
            }
            element "Infrastructure Node" {
                shape roundedbox
            }
            element "iOS" {
                shape MobileDevicePortrait
            }
        }

        themes https://static.structurizr.com/themes/amazon-web-services-2020.04.30/theme.json
    }
}```

Support for specifying element coordinates and relationship control points?

Hi Simon, Iโ€™m just now trying out the DSL for a real project, and so far Iโ€™m very impressed!

One question: I donโ€™t see a way to specify element coordinates and/or relationship control points, when not using auto-layout. Am I missing something, or is this just not yet supported? If the latter, do you intend to add such support at some point?

Thanks!
Avi

Support for URL on objects

Hi @simonbrowndotje ,

There doesn't appear to be any support for setting the URL on any of the objects that accept it in the UI. It this something that can be added?

By the way, I'm really liking the DSL. I much prefer it over the UI.

Cheers!

Kyle

Defining styles resets complete default structurizr style

I really like the default styling when exporting a dsl file to structurizr plantuml format. What I would like to do now is to easily add icons for certain element types (tags) but keep the rest. Using styles and the themes (did not try it yet) I can easily add icons and other style information.

But when styles is being used in a dsl then automatically all styling is gone/reset. My proposal would be that there should be a switch whether using styles in a dsl resets the complete styling or the given default styles should just override the specific style settings.

As a workaround getting the complete default styling to be added to the dsl and changing it where required would also be fine.

Add elements to a view based upon tag(s)

Hello,

I tried to generate some filtered views based on tags for a more complex view. Even though the elements are filtered properly, the diagram generated with autoLayout doesn't look good: looks like it firstly generate the complex diagram with all elements with autolayout, and then show/hide the elements with the specified tags. As a result, the elements are not distributed properly. I would like to first filter elements and then apply the autolayout, so the diagram would look better.

I created a sample DSL code to help me on explaining the issue so you can also reproduce it.

I have a container diagram like this (see #All_Containers):
image

Then I create two filtered views, generating the following diagrams:

#All_Containers_tag1:
image

#All_Containers_tag2:
image

I would like them to be generated in this way:
#All_Containers_tag1_expectation:
image

#All_Containers_tag2_expectation:
image

If there is any way to achive my goal, let me know.

Thanks for your support.

Sample DSL:

workspace "Amazon Web Services Example" "An example AWS deployment architecture." {
    model {
        springPetClinic = softwaresystem "Spring PetClinic" "Allows employees to view and manage information regarding the veterinarians, the clients, and their pets." "Spring Boot Application"{
            app = container "Mobile App" "Show information regarding the veterinarians, the clients, and their pets." "android" "Mobile App, tag1, tag2"
            api1 = container "API 1" "API 2" "Java and Spring Boot" "tag1"
            api2 = container "API 2" "API 2" "Java and Spring Boot" "tag2"
            database = container "Database" "Stores information regarding the veterinarians, the clients, and their pets." "Relational database schema" "Database, tag1"
        }
        thirdPartyApi1 = softwaresystem "Third-Party API 1" "" "tag1"
        thirdPartyApi2 = softwaresystem "Third-Party API 2" "" "tag2"
        
        app -> api1 "manages data" "AWS API Gateway" "tag1"
        app -> api2 "manages data" "AWS API Gateway" "tag2"
        api1 -> database "Reads from and writes to" "JDBC/SSL" "tag1"
        api1 -> thirdPartyApi1 "Get 3rd pary data" "HTTP" "tag1"
        api2 -> thirdPartyApi2 "Get 3rd pary data" "HTTP" "tag2"

        
    }
         
    views {
        container springPetClinic "All_Containers" {
            include *
            autoLayout
        }
        
        container springPetClinic "All_Containers_tag1_expectation" {
            include app api1 database thirdPartyApi1
            autoLayout
        }
        
        container springPetClinic "All_Containers_tag2_expectation" {
            include app api2 thirdPartyApi2
            autoLayout
        }
        
        filtered All_Containers include "tag1, tag2" "All_Containers_tag1_tag2"
        filtered All_Containers include "tag1" "All_Containers_tag1"
        filtered All_Containers include "tag2" "All_Containers_tag2"
        

        styles {
            element "Element" {
                shape roundedbox
                background "#ffffff"
            }
            element "Database" {
                shape cylinder
            }
            element "Mobile App" {
                shape MobileDeviceLandscape
            }
            element "Infrastructure Node" {
                shape roundedbox
            }
        }

        themes https://static.structurizr.com/themes/amazon-web-services-2020.04.30/theme.json
    }
}

Add escape sequence for double quotes

Any property containing " ends up producing the error message com.structurizr.dsl.StructurizrDslParserException: Expected: <name> <value> at line 10: myproperty "This is an \"example\""

Example:

properties {
    myproperty "This is an \"example\""
}

We need a way to escape double quotes. A backslash does obviously not work currently.

Background: We use properties to attach structured data (JSON format) to model elements. JSON requires to use doublequotes for fields.

Workspace empty if it starts with a special comment

The following example retuns a completely empty workspace. Even the comment at the beginning is a valid one, the parser seems not to be able to handle the closing **/

/**
this is a comment
**/

workspace "Getting Started" "This is a model of my software system." {

    model {
        user = person "User" "A user of my software system."
        softwareSystem = softwareSystem "Software System" "My software system."

        user -> softwareSystem "Uses"
    }

    views {
        systemContext softwareSystem "SystemContext" "An example of a System Context diagram." {
            include *
            autoLayout
        }

        styles {
            element "Software System" {
                background #1168bd
                color #ffffff
            }
            element "Person" {
                shape person
                background #08427b
                color #ffffff
            }
        }
    }
    
}

Add more advanced features for groups

Nowadays structurizr allows creating groups of elements, but with some limitations:

  • It is not possible to create nested groups
  • It is not possible to create relationships using groups (element from/to group, group from/to group). At least I was not able to make it working.
  • An element cannot be part of more than one group.
  • When defining a group, we need to explicitelly list the elements in the group. We cannot create a group based on tags.
  • They are automatially displayed. There is no option to decide if we want to group or not elements in a view. Or even select the specific grouping we want to see.

It would be great if we remove these limitations, allowing creating views like this:

  • Layers: I could create some groups representing layers: Experience Layer, API Layer, .... and I could include elements in the group based on tags. Then, when rendering, I could see the elements together within the same layer.
  • Domains: I could also create some groups representing domains: Consumer, Products, Orders, ... and I could include elements based on tags. Notice that a speficic element would be part of a Domain and Layer group, so in this view I would like to only group based on Domain and not on Layer.
  • Ownership: In a very high level, I could group elements by owner areas within a big organization, having groups of groups. I could represent some elements in a group are connected to others in another group, without adding specific relationship between elements.

In case you think there is another recommended to get it, please let me know. Thanks!

Docs suggestion: allowed relationships and allowed relationship locations

Hi,

This is a couple of suggestions for the DSL Language Reference (dsl/blob/docs/language-reference.md).

It seems like there are locations within the DSL structure where you aren't allowed to place relationships. For example. you can put a relationship within a DeploymentEnvironment, but not within a DeploymentNode.

Would it be possible to add that to the language reference, perhaps in the "relationship" section?

Also, is there a restriction on which two element types are allowed a relationship between them?

I managed to trigger the below error when making a relationship from a deploymentNode to a containerInstance:

(

throw new RuntimeException("A relationship between \"" + sourceId + "\" and \"" + destinationId + "\" is not permitted");
).

Perhaps you could document which elements are allowed to have relationships between each other?

Cheers!

Kirk

define relationships within a a container

Hi there,

I just try to start working with structurize but noticed that I can only define relationships on model level. I expected to be able to create something like this:

container myContainer {
   dummyView = component "View"
   dummyViewModel = component "View Model"
   dummyView-> dummyViewModel
}

If there are good modelling reasons for only allowing relationships on model-level, I appologize for asking this question. To me it seems strange that I have to define relationships within one component or a container outside of it.

Thanks in advance for your help and best regards, Jan

Add the ability to get components cross container view

Hello!

Lately I'm working with Structurizr and having a lot of fun, but I'm looking for specific view I can't get by now.
I want to see a connection from one component in container to other component in container, and actually see in one view two different components from two different containers.

For example, let's look in this DSL:

` model {
customer = person "Personal Banking Customer" "A customer of the bank, with personal bank accounts." "Customer"

    enterprise "Big Bank plc" {
        supportStaff = person "Customer Service Staff" "Customer service staff within the bank." "Bank Staff"
        backoffice = person "Back Office Staff" "Administration and support staff within the bank." "Bank Staff"

        mainframe = softwaresystem "Mainframe Banking System" "Stores all of the core banking information about customers, accounts, transactions, etc." "Existing System"
        email = softwaresystem "E-mail System" "The internal Microsoft Exchange e-mail system." "Existing System"
        atm = softwaresystem "ATM" "Allows customers to withdraw cash." "Existing System"

        internetBankingSystem = softwaresystem "Internet Banking System" "Allows customers to view information about their bank accounts, and make payments." {
            singlePageApplication = container "Single-Page Application" "Provides all of the Internet banking functionality to customers via their web browser." "JavaScript and Angular" "Web Browser"
            mobileApp = container "Mobile App" "Provides a limited subset of the Internet banking functionality to customers via their mobile device." "Xamarin" "Mobile App" {
                mobileAppComponent = component "Mobile App Component"
            }
            webApplication = container "Web Application" "Delivers the static content and the Internet banking single page application." "Java and Spring MVC"
            apiApplication = container "API Application" "Provides Internet banking functionality via a JSON/HTTPS API." "Java and Spring MVC" {
                signinController = component "Sign In Controller" "Allows users to sign in to the Internet Banking System." "Spring MVC Rest Controller"
                accountsSummaryController = component "Accounts Summary Controller" "Provides customers with a summary of their bank accounts." "Spring MVC Rest Controller"
                resetPasswordController = component "Reset Password Controller" "Allows users to reset their passwords with a single use URL." "Spring MVC Rest Controller"
                securityComponent = component "Security Component" "Provides functionality related to signing in, changing passwords, etc." "Spring Bean"
                mainframeBankingSystemFacade = component "Mainframe Banking System Facade" "A facade onto the mainframe banking system." "Spring Bean"
                emailComponent = component "E-mail Component" "Sends e-mails to users." "Spring Bean"
            }
            database = container "Database" "Stores user registration information, hashed authentication credentials, access logs, etc." "Oracle Database Schema" "Database"
        }
    }

    # relationships between people and software systems
    customer -> internetBankingSystem "Views account balances, and makes payments using"
    internetBankingSystem -> mainframe "Gets account information from, and makes payments using"
    internetBankingSystem -> email "Sends e-mail using"
    email -> customer "Sends e-mails to"
    customer -> supportStaff "Asks questions to" "Telephone"
    supportStaff -> mainframe "Uses"
    customer -> atm "Withdraws cash using"
    atm -> mainframe "Uses"
    backoffice -> mainframe "Uses"

    # relationships to/from containers
    customer -> webApplication "Visits bigbank.com/ib using" "HTTPS"
    customer -> singlePageApplication "Views account balances, and makes payments using"
    customer -> mobileApp "Views account balances, and makes payments using"
    webApplication -> singlePageApplication "Delivers to the customer's web browser"

    # relationships to/from components
    singlePageApplication -> signinController "Makes API calls to" "JSON/HTTPS"
    singlePageApplication -> accountsSummaryController "Makes API calls to" "JSON/HTTPS"
    singlePageApplication -> resetPasswordController "Makes API calls to" "JSON/HTTPS"
    mobileAppComponent -> signinController "Makes API calls to" "JSON/HTTPS"
    mobileApp -> accountsSummaryController "Makes API calls to" "JSON/HTTPS"
    mobileApp -> resetPasswordController "Makes API calls to" "JSON/HTTPS"
    signinController -> securityComponent "Uses"
    accountsSummaryController -> mainframeBankingSystemFacade "Uses"
    resetPasswordController -> securityComponent "Uses"
    resetPasswordController -> emailComponent "Uses"
    securityComponent -> database "Reads from and writes to" "JDBC"
    mainframeBankingSystemFacade -> mainframe "Makes API calls to" "XML/HTTPS"
    emailComponent -> email "Sends e-mail using"

 
views {

    component apiApplication "Components" {
        include *
        animation {
            singlePageApplication mobileApp database email mainframe
            signinController securityComponent
            accountsSummaryController mainframeBankingSystemFacade
            resetPasswordController emailComponent
        }
        autoLayout
    }

    }
}

}
`

Taken from this example with few modification: https://structurizr.com/dsl?example=big-bank-plc, and I'm taking a look on the component view:
component apiApplication "Components" { include * animation { singlePageApplication mobileApp database email mainframe signinController securityComponent accountsSummaryController mainframeBankingSystemFacade resetPasswordController emailComponent } autoLayout }

The drawing we're having is:

Screen Shot 2021-04-26 at 11 35 50

Even though component inside the mobileApp container is communicating with one of the applications in the API Application container, the connection seems straight from the container itself.
I know that's the intention, but what I wanted to have is the possibility to see also the component inside the "mobileApp" container with dotted lines around the mobileApp container.

I guess it will require a different view, because such kind of view not falling on any of component / container / SystemLandscape view.
Such view (with inner components of several containers) can be quite loaded, so I guess using it with filtered view is the way to go (seeing only connection relevant to this drawing)

The benefit of this kind of view is seeing connection cross containers, and no only in the container level
In the project I'm working in, we're having few containers, each one of them including several processes (components).
My wish is to demonstrate connection between components, and that's where this request coming from

Thanks! Omri

deploymentNode documentation is recursive

### deploymentNode

The `deploymentNode` keyword is used to define a deployment node.
    
    deploymentNode <name> [description] [technology] [tags] [instances] {
         ...
    }

I'm struggling to work out how the deploymentNode keyword should be used and what the concept represents. Some examples of what this represents would be useful, such as those included in the infrastructureNode documentation.

https://github.com/structurizr/dsl/blob/master/docs/language-reference.md#deploymentnode

Property "relations" on perspective "Deployment - production" must be an array

The following DSL does not output any relations for Deployment - production:

workspace "Example" "bla bla" {
    model {
        enterprise "Ent" {
            studio = softwaresystem "Studio" "bla" {
                this_api = container "This API" "Pairing and heartbeat" "REST"
                that_api = container "That API" "" "GraphQL"
            }
            player = softwareSystem "Player" "bla bla"
        }
        google = softwareSystem "GCP" {
            firestore = container "Firestore" "" "" "Google Cloud Platform - Cloud Firestore" 
        }
        cdn = softwareSystem "CDN" "Cloudflare" 
        aws = softwareSystem "AWS" {
            redis = container "Cache" "Redis"
            postgres = container "Database" "PostgreSQL" ""
        }

        deploymentEnvironment "production" {
            deploymentNode "AWS" "" "" "Amazon Web Services - Cloud" {
                deploymentNode "US-East-1" "" "" "Amazon Web Services - Region" {
                    deploymentNode "EC2" "" "" "Amazon Web Services - EC2" {
                        this_api_instance = containerInstance this_api
                        that_api_instance = containerInstance that_api
                    }
                    deploymentNode "RDS" "" "" "Amazon Web Services - RDS PostgreSQL instance" {
                        postgres_instance = containerInstance postgres
                    }
                    deploymentNode "Redis" "" "" "Amazon Web Services - ElastiCache For Redis" {
                        redis_instance = containerInstance redis
                    }
                }
            }
        }
        that_api -> postgres "Reads and writes"
        player -> this_api "Reads and writes (pairing)"
        player -> that_api "Reads and writes (content)"
    }
    views {
        systemContext "studio" {
            include *
            autoLayout
        }
        container "studio" {
            include *
            autoLayout
        }
        container "google" {
            include *
            autoLayout
        }
        deployment studio "production" {
            include *
            autolayout lr
        }
        themes default https://static.structurizr.com/themes/amazon-web-services-2020.04.30/theme.json 
    }
}

Here is the generated IDL:

resources:

  - id: "1"
    name: "Studio"
    subtitle: "[Software System]"
    description: "bla"
    backgroundColor: "#1168bd"
    color: "#ffffff"

    children:
      - id: "2"
        name: "This API"
        subtitle: "[Container: REST]"
        description: "Pairing and heartbeat"
        backgroundColor: "#438dd5"
        color: "#ffffff"

      - id: "3"
        name: "That API"
        subtitle: "[Container: GraphQL]"
        backgroundColor: "#438dd5"
        color: "#ffffff"

  - id: "4"
    name: "Player"
    subtitle: "[Software System]"
    description: "bla bla"
    backgroundColor: "#1168bd"
    color: "#ffffff"

  - id: "5"
    name: "GCP"
    subtitle: "[Software System]"
    backgroundColor: "#1168bd"
    color: "#ffffff"

    children:
      - id: "6"
        name: "Firestore"
        subtitle: "[Container]"
        backgroundColor: "#438dd5"
        color: "#ffffff"

  - id: "7"
    name: "CDN"
    subtitle: "[Software System]"
    description: "Cloudflare"
    backgroundColor: "#1168bd"
    color: "#ffffff"

  - id: "8"
    name: "AWS"
    subtitle: "[Software System]"
    backgroundColor: "#1168bd"
    color: "#ffffff"

    children:
      - id: "10"
        name: "Content database"
        subtitle: "[Container]"
        description: "PostgreSQL"
        backgroundColor: "#438dd5"
        color: "#ffffff"

      - id: "9"
        name: "Cache"
        subtitle: "[Container]"
        description: "Redis"
        backgroundColor: "#438dd5"
        color: "#ffffff"

  - id: "11"
    name: "AWS"
    subtitle: "[Deployment Node]"
    backgroundColor: "#ffffff"
    color: "#232f3e"

    children:
      - id: "12"
        name: "US-East-1"
        subtitle: "[Deployment Node]"
        backgroundColor: "#ffffff"
        color: "#147eba"

        children:
          - id: "13"
            name: "EC2"
            subtitle: "[Deployment Node]"
            backgroundColor: "#ffffff"
            color: "#d86613"

            children:
              - id: "14"
                name: "This API"
                subtitle: "[Container: REST]"
                description: "Pairing and heartbeat"
                backgroundColor: "#438dd5"
                color: "#ffffff"

              - id: "15"
                name: "That API"
                subtitle: "[Container: GraphQL]"
                backgroundColor: "#438dd5"
                color: "#ffffff"

          - id: "16"
            name: "RDS"
            subtitle: "[Deployment Node]"
            backgroundColor: "#ffffff"
            color: "#3b48cc"

            children:
              - id: "17"
                name: "Content database"
                subtitle: "[Container]"
                description: "PostgreSQL"
                backgroundColor: "#438dd5"
                color: "#ffffff"

          - id: "18"
            name: "Redis"
            subtitle: "[Deployment Node]"
            backgroundColor: "#ffffff"
            color: "#3b48cc"

            children:
              - id: "19"
                name: "Cache"
                subtitle: "[Container]"
                description: "Redis"
                backgroundColor: "#438dd5"
                color: "#ffffff"

perspectives:
  - name: Static Structure
    relations:
      - from: "1"
        to: "8"
        label: "Reads and writes"

      - from: "4"
        to: "1"
        label: "Reads and writes (pairing)"

      - from: "1"
        to: "10"
        label: "Reads and writes"

      - from: "3"
        to: "10"
        label: "Reads and writes"

      - from: "3"
        to: "8"
        label: "Reads and writes"

      - from: "4"
        to: "2"
        label: "Reads and writes (pairing)"

      - from: "4"
        to: "3"
        label: "Reads and writes (content)"

  - name: Deployment - production
    relations:

Support parallel activities in dynamic view

At the moment the dynamic view always resolves to a single sequence of activities.
But some flows are more than just a sequence of steps but also includes parallel steps.
It would be very nice if parallel activities (two or three times a 1. or 3.) could be defined too.

Include and exclude by tag

Hi there,

is it possible to include and exclude objects by tag? I just want to separate some elements of a context diagram into grouped items and create additional diagrams. Documentation says we can include/exclude only by name and it looks a bit tedious if we have 2-3 or more groups.
Is there a better way?

views {
systemContext System "SystemContext" "System Context diagram." {
include *

        # exclude Grouped systems
        exclude System1 System2 System3

        # exclude Grouped relationships
        exclude rel_System1 rel_System2 rel_System3

        autoLayout
    }

    systemContext Grouped "Group1" "System Context diagram." {

        # include Grouped systems
        include System1 System2 System3

        # exclude relationship to Group
        exclude rel_to_Grouped
        autoLayout
    }

Converting a DSL into an image file

I can't quite figure out how to use structurizr

Using the web

  • Using the cloud version, there's a demo editor which I can use and render images. The weirdness about this editor is that it's not tied to my workspace, so I need copy-paste my DSL and save it into files locally. This works, but seems to be a terribly UX. It's only a matter of time before I end up losing information with poor copy-pasting.

  • Via my personal workspace, there seems to be no way to edit DSL. If there is, I can't figure out how to it. So it can render, but I can't type anywhere.

Using the cli

  • Using the CLI I can convert my DSL into various other formats, but not into an image file. It seems that you guys use graphviz to render the image, but the CLI cannot export to graphviz.

  • I can use the CLI to upload my DSL, but that's a dead end. I then have to log into the website, and navigate my way around onto the image. For each change I make, I need to re-do the whole round trip (and this is certainly something not scriptable). Each change I make, I need to:

    • Save file.
    • Use cli to upload (this is suuuper slow!)
    • Reload the webpage

So far, it seems that just using the demo editor and copy-pasting is the best way to use structurizr (which is weird, since it makes all the paid features entirely irrelevant). Am I missing something here?

Support for multiple component layers

We have systems with very few but very big containers (Eclipse IDE client application). Such a container consists of a few high level components which itself contain (sub-)components on its own (sometimes even one more component layer) until finally the code layer is reached.
It would be very helpful if the dsl and finally then also the cli and structurizr server would support multiple layers of components.

That means when defining views in the dsl it would be very helpful if only the directly contained elements are shown, that means the component view only shows the top level components of the given container. For lower component layers it would be nice if the "parent" component could be given as the context for the view.

Directory based includes

Use Case: Using Structurizr to model an application landscape.

This goes against the recommendations for using Structurizr, but I have started to model a number (20ish) complex enterprise applications and how they integrate. We have tried this a number of times with UML and other techniques but have all failed, so I am trying it with C4 now :)

I have a models directory, and within that directories for:

  • systems
  • people
  • relationships

I have a modified version of dsl which understands importing from directories.

Effectively I model systems in their own files, containing "within system" relationships in these files.

In the workspace I include the system in scope under "enterpise" and then import all systems next (this filters out the already loaded file in "enterprise"). Workspaces are generally containers for views.

Inter-thing relationships are seperate and included last so as to not require loading in a special order.

Is this something that is interesting? My current code breaks the file handling abstraction in the code a little, to dedeup file includes per workspace (I use Maven to generate all the models, and then also generate ascii doc extracts from the model to be included in other documents).

I can keep this as a private fork, or potenitally share for comment?

Thanks
Chris

=snip=

`
workspace "My System" "System which supports integration" {
model {

    enterprise "My System" {
        !include high-level-system/my-system.dsl
    }

    # Include related Systems here
    !include high-level-system

    # Include related People here
    !include transpower-people
    !include customer-people
    !include relationships

}

views {

    systemLandscape CriticalESBSystemLandscape "All Systems in the ESB System Context" {
        autoLayout

`

What model elements can be imported via !include keyword

I am still working on a VS Code extension and completing a corresponding Xtext Grammar for the DSL.

The !include feature is not yet implemented, but I want to do that soon.

Are there any rules/conventions what kind of model elements/fragments can be outsourced into files, which then can be imported with the !include keyword?

I found the one example

user = person "User" "A user of my software system."
softwareSystem = softwareSystem "Software System" "My software system."

user -> softwareSystem "Uses"

Is that the complete list? Persons, Software Systems (and sub-elements) and Relationships ?

Thanks,
Torsten

Multiple views for same Container

I have a container for which I want to show multiple views, One would be a view that shows the use cases that are provided by the service/container and another would be the actual components that are implemented within the container. I can create the views by having the use cases tagged and include the tag within the view and exclude it in the other view. The views are correctly created but issue is when i want to zoom in on the container view. There seems to be no way that I can enforce/select to which view I want to go. Is that assumption correct, or is there a way to somehow force/select the proper zoom view

autoLayout not working in Deployment Diagrams with relationship between deployment nodes

Hello,

I tried to generate a deployment diagram but I had to disable autoLayout to be able to get it as expected. I created a sample DSL code to help me on explaining the issue so you can also reproduce it.

I have a container diagram like this (see #All_Containers):

image

So, as a summary, a mobile app calls to multiple APIs through an API Gateway. The APIs have integration with database and 3rd party APIs.

For creating the deployment diagram, I added a the API Gateway as an infrastructure node, and enabled relationships between mobile app -> api gw -> apis. On the other hand, I represented a deployment of the APIs in multiple regions.

In the first try, I got the following diagram (See #All_Deployment_1):
image

That deployment diagram was confusing, as it included all relationships, when some of them are not valid from deployment point of view. e.g., API 1 deployed to US is not connected to the database in EU. On the other hand, once I introduce the API Gateway into the diagram, the direct relationship between mobile app and APIs must be hidden.

I've been able to implement the expected diagram using the feature that allows including/excluding especific relationships (See: #All_Deployment_2):

image

However, I had to disable autoLayout and manually distribute the elements in the diagram. If I enable autoLayout, I get the following diagram:

image

I would like to use the autolayout feature, as I do for other diagrams. I would appreciate if you can improve it to allow autolaout in that scenario.
Please let me know if I doing something wrong or I should I take a different approch to generate the deployment diagram as expected.

Thanks for your support.

Sample DSL:

workspace "Amazon Web Services Example" "An example AWS deployment architecture." {
    model {
        springPetClinic = softwaresystem "Spring PetClinic" "Allows employees to view and manage information regarding the veterinarians, the clients, and their pets." "Spring Boot Application" {
            app = container "Mobile App" "Show information regarding the veterinarians, the clients, and their pets." "android" "Mobile App"
            api1 = container "API 1" "API 2" "Java and Spring Boot"
            api2 = container "API 2" "API 2" "Java and Spring Boot"
            database = container "Database" "Stores information regarding the veterinarians, the clients, and their pets." "Relational database schema" "Database"
        }
        thirdPartyApi1 = softwaresystem "Third-Party API 1"
        thirdPartyApi2 = softwaresystem "Third-Party API 2"
        
        app -> api1 "manages data" "AWS API Gateway"
        app -> api2 "manages data" "AWS API Gateway"
        api1 -> database "Reads from and writes to" "JDBC/SSL"
        api1 -> thirdPartyApi1 "Get 3rd pary data" "HTTP"
        api2 -> thirdPartyApi2 "Get 3rd pary data" "HTTP"

        deploymentEnvironment "Live" {
            
            mobilePhone = deploymentNode "Customer's mobile device" "" "Android" {
                appInstance = containerInstance app
            }
            
            deploymentNode "Amazon Web Services" "" "" "Amazon Web Services - Cloud" {
                
                apiGw = deploymentNode "API Gateway" "" "" "Amazon Web Services - API Gateway" {
                    infrastructureNode "API Gateway" "" "" "Amazon Web Services - API Gateway Endpoint"
                }
                
                deploymentNode "US-East-1" "" "" "Amazon Web Services - Region" {
                    
                    apiUsGroup = deploymentNode "Autoscaling group" "" "" "Amazon Web Services - Auto Scaling" {
                        api1UsDeploymentNode = deploymentNode "Amazon EC2 - API 1" "" "" "Amazon Web Services - EC2" {
                            containerInstance api1
                        }
                        api2UsDeploymentNode = deploymentNode "Amazon EC2 - API 2" "" "" "Amazon Web Services - EC2" {
                            containerInstance api2
                        }
                    }
                    
   
                    rdsUs = deploymentNode "Amazon RDS" "" "" "Amazon Web Services - RDS" {
                        deploymentNode "MySQL" "" "" "Amazon Web Services - RDS_MySQL_instance" {
                            containerInstance database
                        }
                    }

                }
                
                deploymentNode "EU-West-1" "" "" "Amazon Web Services - Region" {
                    
                    apiEuGroup = deploymentNode "Autoscaling group" "" "" "Amazon Web Services - Auto Scaling" {
                        api1EuDeploymentNode = deploymentNode "Amazon EC2 - API 1" "" "" "Amazon Web Services - EC2" {
                            containerInstance api1
                        }
                        api2EuDeploymentNode = deploymentNode "Amazon EC2 - API 2" "" "" "Amazon Web Services - EC2" {
                            containerInstance api2
                        }
                    }
                    
   
                    rdsEu = deploymentNode "Amazon RDS" "" "" "Amazon Web Services - RDS" {
                        deploymentNode "MySQL" "" "" "Amazon Web Services - RDS_MySQL_instance" {
                            containerInstance database
                        }
                    }

                }
            }
            
            thirdPartyInfra = deploymentNode "3rd party infrastructure" {
                softwareSystemInstance thirdPartyApi1
                softwareSystemInstance thirdPartyApi2
            }
            
            
            mobilePhone -> apiGw
            apiGw -> apiUsGroup "Forwards requests to" "HTTPS"
            apiGw -> apiEuGroup "Forwards requests to" "HTTPS"
            
            api1UsDeploymentNode -> rdsUs
            api1UsDeploymentNode -> thirdPartyInfra
            api2UsDeploymentNode -> thirdPartyInfra
            
            api1EuDeploymentNode -> rdsEu
            api1EuDeploymentNode -> thirdPartyInfra
            api2EuDeploymentNode -> thirdPartyInfra
        }
    }
         
    views {
        container springPetClinic "All_Containers" {
            include *
            autoLayout
        }
        deployment springPetClinic "Live" "All_Deployment_1" {
            include *
            autoLayout
        }
        
        
        deployment springPetClinic "Live" "All_Deployment_2" {
            include *
            exclude * -> *
            include mobilePhone -> *
            include apiGw -> *
            include api1UsDeploymentNode -> *
            include api2UsDeploymentNode -> *
            include api1EuDeploymentNode -> *
            include api2EuDeploymentNode -> *
            //autoLayout
        }
        

        styles {
            element "Element" {
                shape roundedbox
                background "#ffffff"
            }
            element "Database" {
                shape cylinder
            }
            element "Mobile App" {
                shape MobileDeviceLandscape
            }
            element "Infrastructure Node" {
                shape roundedbox
            }
        }

        themes https://static.structurizr.com/themes/amazon-web-services-2020.04.30/theme.json
    }
}

Fix the typo in softwareSystem definition

Please fix this
[<identifier> = ]softwareSystem = softwareSystem <name> [description] [tags] {

it should really read as
[<identifier> = ] softwareSystem <name> [description] [tags] {

Excluded relationship ignored in Deployment views

Hello,
I've created a deployment diagram like this:

deployment myAppSystem "Live" "LiveDeployment" {
            include deploymentNode1 deploymentNode2
            exclude deploymentNode3
            exclude relationship
            autoLayout
}

So, I want the diagram to include some deployments nodes but hide others. Additionally, I want a relationship between some containers to be hidden.
As a result, I see the deployment nodes are shown as expected, but the relationship between containers is not excluded. Not sure if it also happens with relationship between systems.
It would be great if you can find a way to fix it.

Thank you,
Juan

Optout option for autoAddRelations

Follow Up on #7

We're currently evaluating to use the DSL to hold our documentation as code. Furthermore we thought that we will get rid of this auto add relations to all views where the appropriate components are in feature. Unfortunately, this was a false positive.

After some readings in the implementation, we found out, that it might be easy to add an opt out for this feature into the DSL. The underlying java-client do already implement the necessary part for it in it's API. So, something like this should be possible:

workspace {

    model {
        user = person "User" "A user of my software system."
        softwareSystem = softwareSystem "Software System" "My software system."
        softwareSystem2 = softwareSystem "Software System2" "My software system."
        softwareSystem3 = softwareSystem "Software System3" "My software system."

        uss = user -> softwareSystem "Uses"
        uss2 = user -> softwareSystem2 "Uses"
        uss3 = user -> softwareSystem3 "Uses"
        ss2ss3 = softwareSystem2 -> softwareSystem3 "Uses"
    }

    views {
        systemContext softwareSystem {
            # opt out
            disableAutoAddRelations
            include user softwareSystem2 uss uss2
            autoLayout
        }
    }
    
}

Do you thing that this makes sense?

So, what is actually our need here. We want to document a big system, which does not really have a clean architecture where everything is somehow interconnected with all the other systems. A little bit overdrawing here, but basically we do have the need, to split things into dedicated views for a given context. In the and, we may have several views with same elements but just showing the relationships relevant for the given context.

Maybe this approach is wrong in first place?!

Defining scalable deployment nodes

I am currently in the process of modeling a backend system using the structurizr dsl. One part includes defining our different deployment environment which also differ in regards of scaling the services. A lot of our services are not static but instead have autoscaling implemented. However, I haven't found a good way to model this in the dsl.

Example how I modeled one of our services in a deployment environment:

model {
    deploymentEnvironment production {
        deploymentNode "My scalable service" "This service scales based on load" "Kubernetes Deployment" "2" {
            containerInstance myJavaApplication
            containerInstance istio
        }
    }
}

Intuitively, I wanted to assign a value range, e.g. "2-10" to the last parameter of the deploymentNode field. However, structurizr-cli errors telling me that parameter only accepts numbers as a value.

Are there any suitable options to express the autoscaling of a service in the dsl? if not, would this be a viable feature to support?

Different behaviour dsl compared to code: multiple relationships definitions between same elements

We recently converted from code to the DSL.

It seems there may be different behaviour when defining multiple relationships between the same elements.

For example for the DSL:

"a" -> "b" "text 1"
"a" -> "b" "text 2"

For the DSL this only draws a single line, with the first explanation, so text 1.
In code multiple lines would be drawn. (We used the Java client.)

Not sure if this is a bug or a feature of the DSL but we used these definitions regularly.

We can work around it by combining all texts on a single relationship but first feel is it more arrows is more clear than more text on single relationship.

View Component include component with children

Given the following:

apiApplication = container "API Application" "Desc" "Techno" {
    component1 = component "Test component 1" "Desc" "Techno" "Microservice"
    component2 = component "Test component 2" "Desc" "Techno" "Microservice"
    component1 -> component2
}

I'd like to create a component view showing only component1 and its children, doing the following:

views {
    component apiApplication "Component1" {
        include component1 -> *
    }
}

But that won't work and will throw the following error (using Structurizr CLI v1.8.1):

com.structurizr.dsl.StructurizrDslParserException: The element "component1" does not exist in the view at line 211: include component1 -> *
	at com.structurizr.dsl.StructurizrDslParser.parse(StructurizrDslParser.java:561)

Dynamic view doesn't add relation tag properly

Given the following DSL:

workspace {
    model {
        A = softwareSystem A "" {
            aa = container "aa"
        }
        B = softwareSystem B
        // if we enable the following two lines the relationships are tagged correctly
        // aa -> B "relation1" "" "tag1"
        // aa -> B "relation2" "" "tag2"
    }
    views {
        dynamic A "integration" "TAG-123 :: Project Description" {
            aa -> B "relation1" "" "tag1"
            aa -> B "relation2" "" "tag2"
            autolayout
        }
        systemlandscape "SystemLandscape" {
            include *
            autoLayout
        }
    }
}

I am expecting to get two relationships where the first one is tagged with "tag1" and the second is tagged with "tag2".
Currently, it produces two relationships and both are tagged with "tag1".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.