dsl

package
v1.9.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 22, 2024 License: MIT Imports: 9 Imported by: 3

Documentation

Overview

Package dsl implements a Go based DSL that makes it possible to describe softare architecture models following the C4 model (https://c4model.com).

It is recommended to use "dot import" when using this package to write DSLs, for example:

package design

import . "goa.design/model/dsl"

var _ = Design("<name>", "[description]", func() {
    // ...
})

Some DSL functions accept a anonymous function as last argument (such as Design above) which makes it possible to define a nesting structure. The general shape of the DSL is:

Design                              Design
├── Version                         └── Views
├── Enterprise                          ├── SystemLandscapeView
├── Person                              │   ├── Title
│   ├── Tag                             │   ├── AddDefault
│   ├── URL                             │   ├── Add
│   ├── External                        │   ├── AddAll
│   ├── Prop                            │   ├── AddNeighbors
│   ├── Uses                            │   ├── Link
│   └── InteractsWith                   │   ├── Remove
├── SoftwareSystem                      │   ├── RemoveTagged
│   ├── Tag                             │   ├── RemoveUnreachable
│   ├── URL                             │   ├── RemoveUnrelated
│   ├── External                        │   ├── Unlink
│   ├── Prop                            │   ├── AutoLayout
│   ├── Uses                            │   ├── AnimationStep
│   ├── Delivers                        │   ├── PaperSize
│   └── Container                       │   └── EnterpriseBoundaryVisible
│       ├── Tag                         ├── SystemContextView
│       ├── URL                         │   └──  ... (same as SystemLandsapeView)
│       ├── Prop                        ├── ContainerView
│       ├── Uses                        │   ├── AddContainers
│       ├── Delivers                    │   ├── AddInfluencers
│       └── Component                   │   ├── SystemBoundariesVisible
│           ├── Tag                     │   └── ... (same as SystemLandscapeView*)
│           ├── URL                     ├── ComponentView
│           ├── Prop                    │   ├── AddContainers
│           ├── Uses                    │   ├── AddComponents
│           └── Delivers                │   ├── ContainerBoundariesVisible
└── DeploymentEnvironment               │   └── ... (same as SystemLandscapeView*)
    ├── DeploymentNode                  ├── FilteredView
    │   ├── Tag                         │   ├── FilterTag
    │   ├── Instances                   │   └── Exclude
    │   ├── URL                         ├── DynamicView
    │   ├── Prop                        │   ├── Title
    │   └── DeploymentNode              │   ├── AutoLayout
    │       └── ...                     │   ├── PaperSize
    ├── InfrastructureNode              │   ├── Add
    │   ├── Tag                         ├── DeploymentView
    │   ├── URL                         │   └── ... (same as SystemLandscapeView*)
    │   └── Prop                        └── Style
    └── ContainerInstance                   ├── ElementStyle
        ├── Tag                             └── RelationshipStyle
        ├── HealthCheck
        └── Prop                        (* minus EnterpriseBoundaryVisible)

Index

Constants

View Source
const Global = 0

Global is the keyword used to define dynamic views with global scope. See DynamicView.

Variables

View Source
var DefaultEdgeSeparation = 200

DefaultEdgeSeparation sets the default edge separation for auto layout.

View Source
var DefaultImplementation = ImplementationDagre

DefaultImplementation sets tje default implementation for the auto layout.

View Source
var DefaultNodeSeparation = 600

DefaultNodeSeparation sets the default node separation for auto layout.

View Source
var DefaultRankSeparation = 300

DefaultRankSeparation sets the default rank separation for auto layout.

Functions

func Add

func Add(element any, dsl ...func())

Add adds a person or an element to a view.

Add must appear in SystemLandscapeView, SystemContextView, ContainerView, ComponentView or DeploymentView.

Usage depends on the view Add is used in. In all cases Add supports an optional DSL function as last argument that can be used to specify rendering details.

  • In SystemLandscapeView, SystemContextView, ContainerView and ComponentView Add accepts a person, a software system or their names.

  • In ContainerView Add also accepts a container or the path to a container. The path to a container is either its name if it is a child of the the software system the container view is for or the name of the parent software system followed by a slash and the name of the container otherwise.

  • In ComponentView Add also accepts a component or the path to a component. The path of a component is either its name if it is a child of the container the component view is for or the name of the parent software system followed by a slash, the name of the parent container, another slash and the name of the component.

  • In DeploymentView, Add accepts a deployment node, a container instance, an infrastructure node or their paths. The path is constructed by appending the top level deployment node name with the child deployment name recursively followed by the name of the inner deployment node, infrastructure node or container instance. The names must be separated by slashes in the path. For container instances the path may end with the container instance ID.

Usage (SystemLandscapeView, SystemContextView, ContainerView and ComponentView):

Add(Person|"<Person>"[, func()])

Add(SoftwareSystem|"<Software System>"[, func()])

Additionally for ContainerView:

Add(Container[, func()])

Add("<Container>"[, func()]) // If container is a child of the system software
                             // the container view is for.
Add("<Software System/Container>"[, func()])

Additionally for ComponentView:

Add(Component[, func()])

Add("<Component>"[, func()]) // If component is a child of the container the
                             // component view is for.
Add("<Container/Component>"[, func()]) // if container is a child of the
                                       // software system that contains the
                                       // container the component view is for.
Add("<Software System/Container/Component>"[, func()])

Usage (DeploymentView):

Add(DeploymentNode[, func()])

Add(InfrastructureNode[, func()])

Add(ContainerInstance[, func()])

Add("<Deployment Node>"[, func()]) // top level deployment node

Add("<Parent Deployment Node>/.../<Child Deployment Node>"[, func()]) // child deployment node

Add("<Parent Deployment Node>/.../<Infrastructure Node>"[, func()])

Add("<Parent Deployment Node>/.../<Container Instance>:<Container Instance ID>"[, func()])

Where "<Parent Deployment Node>/..." describes a deployment node hierarchy starting with the top level deployment node name followed by its child deployment node name etc.

Example:

var _ = Design(func() {
    var Customer = Person("Customer", "A customer", func() {
        Uses("Software System", "Sends emails", "SMTP")
    })
    var MyContainer *expr.Container
    var System = SoftwareSystem("Software System", "My software system.", func() {
        MyContainer = Container("Container", "A container")
    })
    var OtherSystem = SoftwareSystem("Other System", "My other software system.", func() {
        Container("Other Container", "Another container")
    })
    var Kubernetes *expr.DeploymentNode
    DeploymentEnvironment("Production", func() {
        DeploymentNode("Cloud", func() {
            Kubernetes = DeploymentNode("Kubernetes", func() {
                ContainerInstance(MyContainer) // Same as ContainerInstance("Software System/Container")
                ContainerInstance(MyContainer, func() {
                    InstanceID(2)
                })
            })
            InfrastructureNode("API Gateway")
        })
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            Add(Customer, func() { // Same as Add("Customer", func() {
                Coord(10, 10)
                NoRelationships()
            })
        })
        ContainerView(SoftwareSystem, "container", "A diagram of Software System", func() {
            Add(Customer)
            Add(MyContainer) // Same as Add("Container")
            Add("Other System/Other Container")
        })
        DeploymentView(Global, "Production", "deployment", "A deployment overview diagram.", func() {
            Add("Cloud/Kubernetes/Container")
            Add("Cloud/Kubernetes/Container:2")
            Add("Cloud:API Gateway")
        })
    })
})

func AddAll

func AddAll()

AddAll includes all elements and relationships in the view scope.

AddAll may appear in SystemLandscapeView, SystemContextView, ContainerView, ComponentView or DeploymentView.

AddAll takes no argument.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var Person = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddAll()
        })
    })
})

func AddComponents

func AddComponents()

AddComponents includes all components in scope to the view.

AddComponents must appear in ComponentView.

AddComponents takes no argument

func AddContainers

func AddContainers()

AddContainers includes all containers in scope to the view.

AddContainers may appear in ContainerView or ComponentView.

AddContainers takes no argument.

func AddDefault

func AddDefault()

AddDefault adds default elements that are relevant for the specific view:

  • System landscape view: adds all software systems and people
  • System context view: adds softare system and other related software systems and people.
  • Container view: adds all containers in software system as well as related software systems and people.
  • Component view: adds all components in container as well as related containers, software systems and people.
  • Deployment view: adds all deployment nodes.

AddDefault must appear in SystemLandscapeView, SystemContextView, ContainerView or ComponentView.

AddDefault takes no argument.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddDefault()
        })
    })
})

func AddImpliedRelationships

func AddImpliedRelationships()

AddImpliedRelationships creates implied relationships between all valid combinations of parent elements, unless the same relationship already exists between them. For example if a model includes two containers with one component each and the DSL defines a relationship between the two components (Component 1 to Component 2) then AddImpliedRelationships would add the following relationships:

  • Component 1 to Container 2
  • Container 1 to Component 2
  • Container 1 to Container 2

AddImpliedRelationships must appear in Design.

func AddInfluencers

func AddInfluencers()

AddInfluencers adds all containers of the ContainerView as well as all external influencers, that is all persons and all other software systems with incoming or outgoing dependencies. Additionally, all relationships of external dependencies are omitted to keep the diagram clean.

AddInfluencers must appear in ContainerView.

AddInfluencers takes no argument.

func AddNeighbors

func AddNeighbors(element any)

AddNeighbors Adds all of the permitted elements which are directly connected to the specified element. Permitted elements are software systems and people for system landscape and system context views, software systems, people and containers for container views and software system, people, containers and components for component views.

AddNeighbors must appear in SystemLandscapeView, SystemContextView, ContainerView, ComponentView or DeploymentView.

AddNeighbors accept a single argument which is the element that should be added with its direct relationships. The element is identified by reference or by path. The path consists of the element name if a top level element (person or software system) or if the element is in scope (container in container view software system, container in component view software system or component in component view container). When the element is not in scope the path specifies the parent element name followed by a slash and the element name. If the parent itself is not in scope (i.e. a component that is a child of a different software system in a ComponentView) then the path specifies the top-level software system followed by a slash, the container name, another slash and the component name.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.", func() {
        Container("Container", func() {
            Component("Component")
        })
    })
    SoftwareSystem("Other System", func() {
        Container("Container", func() {
            Component("Component")
        })
    })
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddNeighbors(System)
            AddNeighbors(Customer)
        })
        ComponentView("Software System/Container", func() {
             Add("Component")
             AddNeighbors("Other System/Container/Component")
        })
    })
})

func AnimationStep added in v1.5.0

func AnimationStep(elements ...any)

AnimationStep defines an animation step consisting of the specified elements.

AnimationStep must appear in SystemLandscapeView, SystemContextView, ContainerView, ComponentView or DeploymentView.

AnimationStep accepts the list of elements that should be rendered in the animation step as argument. Each element is identified by reference or by path. The path consists of the element name if a top level element (person or software system) or if the element is in scope (container in container view software system, container in component view software system or component in component view container). When the element is not in scope the path specifies the parent element name followed by a slash and the element name. If the parent itself is not in scope (i.e. a component that is a child of a different software system in a ComponentView) then the path specifies the top-level software system followed by a slash, the container name, another slash and the component name.

Example

var _ = Design(func() {
    SoftwareSystem("Software System", "My software system.")
    var OtherSystem = SoftwareSystem("Other software System")
    var Customer = Person("Customer", func() {
        External()
        Uses("Software System", "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddDefault()
            AnimationStep(OtherSystem, Customer)
            AnimationStep("Software System")
        })
    })
})

func AutoLayout

func AutoLayout(rank RankDirectionKind, args ...func())

AutoLayout enables automatic layout mode for the diagram.

The First argument indicates the rank direction, it must be one of RankTopBottom, RankBottomTop, RankLeftRight or RankRightLeft

AutoLayout must appear in SystemLandscapeView, SystemContextView, ContainerView, ComponentView, DynamicView or DeploymentView.

AutoLayout accepts one or two arguments: the layout rank direction and an optional function DSL that describes the layout properties.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var OtherSystem = SoftwareSystem("Other software System")
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddDefault()
            AutoLayout(RankTopBottom, func() {
                Implementation(ImplementationGraphviz)
                RankSeparation(200)
                NodeSeparation(100)
                EdgeSeparation(10)
                Vertices()
            })
        })
    })
})

func Background

func Background(color string)

Background sets elements background color, default is #dddddd.

Background must appear in ElementStyle.

Background accepts a single argument: the background color encoded as HTML hex value (e.g. "#ffffff").

func Border

func Border(kind BorderKind)

Border sets elements border style, default is BorderSolid.

Border must appear in ElementStyle.

Border takes a single argument: one of BorderSolid, BorderDashed or BorderDotted.

func Color

func Color(color string)

Color sets elements text color, default is #000000.

Color must appear in ElementStyle or RelationshipStyle.

Color accepts a single argument: the color encoded as HTML hex value (e.g. "#ffffff").

func Component

func Component(name string, args ...any) *expr.Component

Component defines a component.

Component must appear in a Container expression.

Component takes 1 to 4 arguments. The first argument is the component name. The name may be optionally followed by a description. If a description is set then it may be followed by the technology details used by the component. Finally Component may take a func() as last argument to define additional properties of the component.

The valid syntax for Component is thus:

Component("<name>")

Component("<name>", "[description]")

Component("<name>", "[description]", "[technology]")

Component("<name>", func())

Component("<name>", "[description]", func())

Component("<name>", "[description]", "[technology]", func())

Example:

var _ = Design(func() {
    SoftwareSystem("My system", "A system with a great architecture", func() {
        Container("My container", "A container with a great architecture", "Go and Goa", func() {
            Component(Container, "My component", "A component", "Go and Goa", func() {
                Tag("bill processing")
                URL("https://goa.design/mysystem")
                Uses("Other Component", "Uses", "gRPC", Synchronous)
                Delivers("Customer", "Delivers emails to", "SMTP", Synchronous)
            })
        })
    })
})

func ComponentView

func ComponentView(container any, key string, args ...any)

ComponentView defines a component view.

ComponentView must appear in Views.

ComponentView accepts 3 to 4 arguments: the first argument is the container or the path to the container being described by the component view. The path consists of the name of the software system that contains the container followed by a slash followed by the name of the container. The following argument is a unique key which can be used to reference the view when creating a filtered views. Next is an optional description. The last argument must be a function describing the properties of the view.

Usage:

ComponentView(Container, "<key>", func())

ComponentView("<Software System>/<Container>", "<key>", func())

ComponentView(Container, "<key>", "[description]", func())

ComponentView("<Software System>/<Container>", "<key>", "[description]", func())

Example:

var _ = Design(func() {
    SoftwareSystem("Software System", "My software system.", func() {
        Container("Container", func() {
            Uses("Other System")
        })
    })
    SoftwareSystem("Other System")
    Views(func() {
        ComponentView("Software System/Container", "component", "An overview diagram.", func() {
            Title("Overview of container")
            AddAll()
            Remove("Other System")
            AutoLayout(RankTopBottom)
            AnimationStep("Software System")
            PaperSize(SizeSlide4X3)
            ContainerBoundariesVisible()
        })
    })
})

func Container

func Container(args ...any) *expr.Container

Container defines a container.

Container must appear in a SoftwareSystem expression.

Container takes 1 to 4 arguments. The first argument is the container name. The name may be optionally followed by a description. If a description is set then it may be followed by the technology details used by the container. Finally Container may take a func() as last argument to define additional properties of the container.

The valid syntax for Container is thus:

Container("<name>")

Container("<name>", "[description]")

Container("<name>", "[description]", "[technology]")

Container("<name>", func())

Container("<name>", "[description]", func())

Container("<name>", "[description]", "[technology]", func())

Container also accepts a Goa service as argument in which case the name and description are taken from the service and the technology is set to "Go and Goa v3"

Container(Service)

Container(Service, func())

Example:

var _ = Design(func() {
    SoftwareSystem("My system", "A system with a great architecture", func() {
        Container("My service", "A service", "Go and Goa", func() {
            Tag("bill processing")
            URL("https://goa.design/mysystem")
            Uses("Other Container", "Uses", "gRPC", Synchronous)
            Delivers("Customer", "Delivers emails to", "SMTP", Synchronous)
        })

        // Alternate syntax using a Goa service.
        Container(Service, func() {
            // ...
        })
    })
})

func ContainerBoundariesVisible

func ContainerBoundariesVisible()

ContainerBoundariesVisible makes the enterprise boundary visible to differentiate internal elements from external elements on the resulting diagram.

ContainerBoundariesVisible must appear in ComponentView.

ContainerBoundariesVisible takes no argument

func ContainerInstance

func ContainerInstance(container any, dsl ...func()) *expr.ContainerInstance

ContainerInstance defines an instance of the specified container that is deployed on the parent deployment node.

ContainerInstance must appear in a DeploymentNode expression.

ContainerInstance takes one or two arguments: the first argument identifies the container by reference or by path (software system name followed by colon and container name). The second optional argument is a func() that defines additional properties on the container instance including the container instance ID.

Usage:

ContainerInstance(Container)

ContainerInstance(Container, func())

ContainerInstance("<Software System>/<Container>")

ContainerInstance("<Software System>/<Container>", func())

Example:

var _ = Design(func() {
    var MyContainer *expr.Container
    SoftwareSystem("SoftwareSystem", "A software system", func() {
        MyContainer = Container("Container")
    })
    DeploymentEnvironment("Production", func() {
        DeploymentNode("US", "US shard", func() {
            ContainerInstance(MyContainer, func() {
                Tag("service")
                InstanceID(1)
                HealthCheck("check", func() {
                    URL("https://goa.design/health")
                    Interval(10)
                    Timeout(1000)
                })
            })
            // Using the name instead:
            ContainerInstance("SoftwareSystem/Container", func() {
                InstanceID(2
            })
        })
    })
})

func ContainerView

func ContainerView(system any, key string, args ...any)

ContainerView defines a container view.

ContainerView must appear in Views.

ContainerView accepts 3 to 4 arguments: the first argument is the software system or the name of the software system the container view applies to. The second argument is a unique key which can be used to reference the view when creating a filtered views. The third argument is an optional description. The last argument is a function describing the properties of the view.

Usage:

ContainerView(SoftwareSystem, "<key>", func())

ContainerView("<Software System>", "<key>", func())

ContainerView(SoftwareSystem, "<key>", "[description]", func())

ContainerView("<Software System>", "<key>", "[description]", func())

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var OtherSystem = SoftwareSystem("Other System")
    Views(func() {
        ContainerView(SoftwareSystem, "container", "An overview diagram.", func() {
            Title("System containers")
            AddAll()
            Remove(OtherSystem)
            // Alternatively to AddAll + Remove: Add
            AutoLayout(RankTopBottom)
            AnimationStep(System)
            PaperSize(SizeSlide4X3)
            SystemBoundariesVisible()
        })
    })
})

func Coord

func Coord(x, y int)

Coord defines explicit coordinates for where to render a person or element.

Coord must appear in Add.

Coord takes two arguments: the X and Y where the person or element is rendered.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(System, "context", "An overview diagram.", func() {
            Add(Customer, func() {
                Coord(200,200)
            })
        })
    })
})

func Dashed added in v1.7.0

func Dashed()

Dashed makes relationship lines dashed.

Dashed must appear in RelationshipStyle.

Dashed takes no argument.

func Delivers

func Delivers(person any, description string, args ...any)

Delivers adds an interaction between an element and a person.

Delivers must appear in SoftareSystem, Container or Component.

Delivers accepts 2 to 5 arguments. The first argument is the target of the relationship, it must be a person or the name of a person. The target may optionally be followed by a short description of the relationship. The description may optionally be followed by the technology used by the relationship and/or the type of relationship: Synchronous or Asynchronous. Finally Delivers accepts an optional func() as last argument to add further properties to the relationship.

Usage:

Delivers(Person|"Person", "<description>")

Delivers(Person|"Person", "<description>", "[technology]")

Delivers(Person|"Person", "<description>", Synchronous|Asynchronous)

Delivers(Person|"Person", "<description>", "[technology]", Synchronous|Asynchronous)

Delivers(Person|"Person", "<description>", func())

Delivers(Person|"Person", "<description>", "[technology]", func())

Delivers(Person|"Person", "<description>", Synchronous|Asynchronous, func())

Delivers(Person|"Person", "<description>", "[technology]", Synchronous|Asynchronous, func())

Example:

var _ = Design("my workspace", "a great architecture model", func() {
    var Customer = Person("Customer")
    SoftwareSystem("MySystem", func () {
       Delivers(Customer, "Sends requests to", "email")
    })
})

func DeploymentEnvironment

func DeploymentEnvironment(name string, dsl func())

DeploymentEnvironment defines a deployment environment (e.g. development, production).

DeploymentEnvironment must appear in a Design expression.

DeploymentEnvironment accepts two arguments: the environment name and a DSL function used to describe the nodes within the environment.

Example:

var _ = Design(func() {
     DeploymentEnvironment("production", func() {
         DeploymentNode("AppServer", "Application server", "Go and Goa v3")
         InfrastructureNote("Router", "External traffic router", "AWS Route 53")
         ContainerInstance(Container)
     })
 })

func DeploymentNode

func DeploymentNode(name string, args ...any) *expr.DeploymentNode

DeploymentNode defines a deployment node. Deployment nodes can be nested, so a deployment node can contain other deployment nodes. A deployment node can also contain InfrastructureNode and ContainerInstance elements.

DeploymentNode must appear in a DeploymentEnvironment or DeploymentNode expression.

DeploymentNode takes 1 to 4 arguments. The first argument is the node name. The name may be optionally followed by a description. If a description is set then it may be followed by the technology details used by the component. Finally DeploymentNode may take a func() as last argument to define additional properties of the component.

Usage:

DeploymentNode("<name>")

DeploymentNode("<name>", "[description]")

DeploymentNode("<name>", "[description]", "[technology]")

DeploymentNode("<name>", func())

DeploymentNode("<name>", "[description]", func())

DeploymentNode("<name>", "[description]", "[technology]", func())

Example:

var _ = Design(func() {
    DeploymentEnvironment("Production", func() {
        DeploymentNode("US", "US shard", func() {
            Tag("shard")
            Instances(3)
            URL("https://goa.design/docs/shard")
            InfrastructureNode("Gateway", "US gateway", func() {
                Tag("gateway")
                URL("https://goa.design/docs/shards/us")
            })
            ContainerInstance("Container", "System", func() {
                Tag("service")
                InstanceID(1)
                HealthCheck("check", func() {
                    URL("https://goa.design/health")
                    Interval(10)
                    Timeout(1000)
                })
            })
            DeploymentNode("Cluster", "K8 cluster", func() {
                // ...
            })
        })
    })
})

func DeploymentView

func DeploymentView(scope any, env, key string, args ...any)

DeploymentView defines a Deployment view for the specified scope and deployment environment. The first argument defines the scope of the view, and the second argument defines the deployment environment. The combination of these two arguments determines what can be added to the view, as follows:

  • Global scope: All deployment nodes, infrastructure nodes, and container instances within the deployment environment.
  • Software system scope: All deployment nodes and infrastructure nodes within the deployment environment. Container instances within the deployment environment that belong to the software system.

DeploymentView must appear in Views.

DeploymentView accepts 4 to 5 arguments: the first argument is the scope: either the keyword 'Global', a software system or the name of a software system. The second argument is the name of the environment. The third argument is a unique key for the view. The fourth argument is an optional description. The last argument is a function describing the properties of the view.

Usage:

DeploymentView(Scope, "<environment>", "<key>", func())

DeploymentView(Scope, "<environment>", "<key>", "[description]", func())

Where Scope is 'Global', a software system or its name.

Example:

var _ = Design(func() {
    SoftwareSystem("System", func() {
         Container("Container")
         Container("OtherContainer")
    })
    DeploymentEnvironment("Production", func() {
        DeploymentNode("Cloud", func() {
            ContainerInstance("System/Container")
            ContainerInstance("System/OtherContainer")
        })
    })
    Views(func() {
        DeploymentView(Global, "Production", "deployment", "A deployment overview diagram.", func() {
            Title("Overview of deployment")
            AddAll()
            Remove("System/OtherContainer")
            AutoLayout(RankTopBottom)
            AnimationStep("System/Container")
            PaperSize(SizeSlide4X3)
        })
    })
})

func Description

func Description(desc string)

Description provides a short description for a relationship displayed in a dynamic view.

Description must appear in Add.

Description takes one argument: the relationship description used in the dynamic view.

func Design added in v1.5.0

func Design(args ...any) *expr.Design

Design defines the architecture design containing the models and views. Design must appear exactly once.

Design is a top-level DSL function.

Design takes one to three arguments. The first argument is either a string or a function. If the first argument is a string then an optional description may be passed as second argument. The last argument must be a function that defines the models and views.

The valid syntax for Design is thus:

Design(func())

Design("name", func())

Design("name", "description", func())

Examples:

// Default workspace, no description
var _ = Design(func() {
    SoftwareSystem("My Software System")
})

// Design with given name, no description
var _ = Design("name", func() {
    SoftwareSystem("My Software System")
})

// Design with given name and description
var _ = Design("My Design", "A great architecture.", func() {
    SoftwareSystem("My Software System")
})

func DynamicView

func DynamicView(scope any, key string, args ...any)

DynamicView defines a Dynamic view for the specified scope. The first argument defines the scope of the view, and therefore what can be added to the view, as follows:

  • Global scope: People and software systems.
  • Software system scope: People, other software systems, and containers belonging to the software system.
  • Container scope: People, other software systems, other containers, and components belonging to the container.

DynamicView must appear in Views.

DynamicView accepts 3 to 4 arguments. The first argument defines the scope: either the keyword 'Global', a software system, a software system name, a container or a container path. The path to a container is the name of the parent software system followed by a slash and the name of the container. The following argument is a unique key for the view. Next is an optional description. The last argument is a function describing the properties of the view.

A dynamic view is created by specifying the relationships that should be rendered via Link.

Usage:

DynamicView(Scope, "<key>", func())

DynamicView(Scope, "<key>", "[description]", func())

DynamicView("SoftwareSystem/Container", "<key>", func())

DynamicView("SoftwareSystem/Container", "<key>", "[description]", func())

Where Scope is 'Global', a software system, a software system name or a container.

Example:

var _ = Design(func() {
    var FirstSystem = SoftwareSystem("First system")
    var SecondSystem = SoftwareSystem("Second system", func() {
        Uses(FirstSystem, "Uses")
    })
    Views(func() {
        DynamicView(Global, "dynamic", "A dynamic diagram.", func() {
            Title("Overview of system")
            Link(FirstSystem, SecondSystem)
            AutoLayout(RankTopBottom)
            PaperSize(SizeSlide4X3)
        })
    })
})

func EdgeSeparation

func EdgeSeparation(sep int)

EdgeSeparation sets the separation between edges in pixels, defaults to 200.

EdgeSeparation must appear in AutoLayout.

EdgeSeparation takes one argument: the edge separation in pixels.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AutoLayout(func() {
                EdgeSeparation(500)
            })
        })
    })
})

func ElementStyle

func ElementStyle(tag string, dsl func())

ElementStyle defines element styles.

ElementStyle must appear in Styles.

ElementStyle accepts two arguments: the tag that identifies the elements that the style should be applied to and a function describing the style properties.

Example:

var _ = Design(func() {
    // ...
    Views(func() {
        // ...
        Styles(func() {
            ElementStyle("default", func() {
                Shape(ShapeBox)
                Icon("https://goa.design/goa-logo.png")
                Background("#dddddd")
                Color("#000000")
                Stroke("#000000")
                ShowMetadata()
                ShowDescription()
            })
        })
    })
})

func Enterprise

func Enterprise(e string)

Enterprise defines a named "enterprise" (e.g. an organisation). On System Landscape and System Context diagrams, an enterprise is represented as a dashed box. Only a single enterprise can be defined within a model.

Enterprise must appear in a Design expression.

Enterprise takes exactly one argument: the enterprise name.

Example:

var _ = Design(func() {
    Enterprise("Goa Design")
})

func EnterpriseBoundaryVisible

func EnterpriseBoundaryVisible()

EnterpriseBoundaryVisible makes the enterprise boundary visible to differentiate internal elements from external elements on the resulting diagram.

EnterpriseBoundaryVisible must appear in SystemLandscapeView or SystemContextView.

EnterpriseBoundaryVisible takes no argument

func Exclude added in v1.5.0

func Exclude()

Exclude indicates that the filtered view should include all elements except the ones identified through the filter tag.

Exclude must appear in FilteredView

Exclude takes no argument.

func External

func External()

External indicates the element is external to the enterprise.

External may appear in Person or SoftwareSystem.

Example:

var _ = Design(func() {
    System("My system", func() {
        External()
    })
})

func FilterTag added in v1.5.0

func FilterTag(tag string, tags ...string)

FilterTag defines the set of tags to include or exclude (when Exclude() is used) elements and relationships when rendering the filtered view.

FilterTag must appear in FilteredView

FilterTag takes the list of tags as arguments. Multiple calls to FilterTag accumulate the tags.

func FilteredView

func FilteredView(view any, dsl func())

FilteredView defines a filtered view on top of the specified view. The base key specifies the key of the System Landscape, System Context, Container, or Component view on which this filtered view should be based.

FilteredView must appear in Views.

FilteredView accepts 2 arguments: the view being filtered or its key and a function describing additional properties.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddAll()
            AutoLayout(RankTopBottom)
        })
        FilteredView(SystemContextView, func() {
            FilterTag("infra")
            Exclude()
        })
    })
})

func FontSize

func FontSize(pixels int)

FontSize sets elements or relationships text font size, default is 24.

FontSize must appear in ElementStyle or RelationshipStyle.

FontSize accepts a single argument: the size of the font in pixels.

func Header(n, v string)

Header defines a header name and value to be set in requests sent for health checks.

Header must appear in a HealthCheck expression.

Header takes two arguments: the header name and value.

Example:

var _ = Design(func() {
    DeploymentEnvironment("Production", func() {
        ContainerInstance(Container, func() {
            HealthCheck("check", func() {
                Header("X-Foo", "bar")
            })
        })
    })
})

func HealthCheck

func HealthCheck(name string, dsl func())

HealthCheck defines a HTTP-based health check for a container instance.

HealthCheck must appear in a ContainerInstance expression.

HealthCheck accepts two arguments: the health check name and a function used to define additional required properties.

Example:

var _ = Design(func() {
    DeploymentEnvironment("Production", func() {
        ContainerInstance(Container, func() {
            HealthCheck("check", func() {
                URL("https://goa.design/health")
                Interval(10)
                Timeout(1000)
                Header("X-Foo", "bar")
            })
        })
    })
})

func Height

func Height(height int)

Height sets elements height, default is 300.

Height must appear in ElementStyle.

Height accepts a single argument: the height in pixel.

func Icon

func Icon(icon string)

Icon sets elements icon. Icon accepts the URL or data URI (https://css-tricks.com/data-uris/) of the icon.

Tip: Generating icons programatically can be done using the "image" package (to draw the image), "image/png" to render the image and "encoding/base64" to encode the result into a data URI.

Icon must appear in ElementStyle.

Icon accepts URL to the icon image or a data URI.

func Implementation added in v1.9.1

func Implementation(impl ImplementationKind)

Implementation sets the implementation of the automatic layout, defaults to ImplementationDagre.

Implementation must appear in AutoLayout.

Implementation takes one argument: the ImplementationKind.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AutoLayout(func() {
                Implementation(ImplementationGraphviz)
            })
        })
    })
})

func InfrastructureNode

func InfrastructureNode(name string, args ...any) *expr.InfrastructureNode

InfrastructureNode defines an infrastructure node, typically something like a load balancer, firewall, DNS service, etc.

InfrastructureNode must appear in a DeploymentNode expression.

InfrastructureNode takes 1 to 4 arguments. The first argument is the infrastructure node name. The name may be optionally followed by a description. If a description is set then it may be followed by the technology details used by the component. Finally InfrastructureNode may take a func() as last argument to define additional properties of the component.

Usage:

InfrastructureNode("<name>")

InfrastructureNode("<name>", "[description]")

InfrastructureNode("<name>", "[description]", "[technology]")

InfrastructureNode("<name>", func())

InfrastructureNode("<name>", "[description]", func())

InfrastructureNode("<name>", "[description]", "[technology]", func())

Example:

var _ = Design(func() {
    DeploymentEnvironment("Production", func() {
        DeploymentNode("US", "US shard", func() {
            InfrastructureNode("Gateway", "US gateway", func() {
                Tag("gateway")
                URL("https://goa.design/docs/shards/us")
            })
        })
    })
})

func InstanceID

func InstanceID(n int)

InstanceID sets the instance number or index of a container instance.

InstanceID must appear in a ContainerInstance expression.

InstanceID accepts a single argument which is the number.

Example:

var _ = Design(func() {
    DeploymentEnvironment("Production", func() {
        ContainerInstance(Container, func() {
            InstanceID(3)
        })
    })
})

func Instances

func Instances(n string)

Instances sets the number of instances of the deployment node.

Instances must appear in a DeploymentNode expression.

Instances accepts a single argument which is a string.

Instances can either be a static number, or a range (e.g. 0..1, 1..3, 5..10, 0..N, 0..*, 1..N, 1..*, etc).

Example:

var _ = Design(func() {
    DeploymentEnvironment("Production", func() {
        DeploymentNode("Web app", func() {
            Instances("3")
        })
    })
})

func InteractsWith

func InteractsWith(person any, description string, args ...any)

InteractsWith adds an interaction between a person and another.

InteractsWith must appear in Person.

InteractsWith accepts 2 to 5 arguments. The first argument is the target of the relationship, it must be a person or the name of a person. The target may optionally be followed by a short description of the relationship. The description may optionally be followed by the technology used by the relationship and/or the type of relationship: Synchronous or Asynchronous. Finally InteractsWith accepts an optional func() as last argument to add further properties to the relationship.

Usage:

InteractsWith(Person|"Person", "<description>")

InteractsWith(Person|"Person", "<description>", "[technology]")

InteractsWith(Person|"Person", "<description>", Synchronous|Asynchronous)

InteractsWith(Person|"Person", "<description>", "[technology]", Synchronous|Asynchronous)

InteractsWith(Person|"Person", "<description>", func())

InteractsWith(Person|"Person", "<description>", "[technology]", func())

InteractsWith(Person|"Person", "<description>", Synchronous|Asynchronous, func())

InteractsWith(Person|"Person", "<description>", "[technology]", Synchronous|Asynchronous, func())

Example:

var _ = Design("my workspace", "a great architecture model", func() {
    var Employee = Person("Employee")
    Person("Customer", "Customers of enterprise", func () {
       InteractsWith(Employee, "Sends requests to", "email")
    })
})

func Interval

func Interval(n int)

Interval defines a health check polling interval in seconds.

Interval must appear in a HealthCheck expression.

Interval takes one argument: the number of seconds.

Example:

var _ = Design(func() {
    DeploymentEnvironment("Production", func() {
        ContainerInstance(Container, func() {
            HealthCheck("check", func() {
                Interval(10)
            })
        })
    })
})
func Link(source, destination any, args ...any)

Link adds a relationship to a view.

Link must appear in SystemLandscapeView, SystemContextView, ContainerView, ComponentView, DynamicView or DeploymentView.

Link takes the relationship as defined by its source, destination and when needed to distinguish its description as first arguments and an optional function as last argument.

The source and destination are identified by reference or by path. The path consists of the element name if a top level element (person or software system) or if the element is in scope (container in container view software system, container in component view software system or component in component view container). When the element is not in scope the path specifies the parent element name followed by a slash and the element name. If the parent itself is not in scope (i.e. a component that is a child of a different software system in a ComponentView) then the path specifies the top-level software system followed by a slash, the container name, another slash and the component name.

Usage:

Link(Source, Destination) // If only one relationship exists between Source
                          // and Destination.
Link(Source, Destination, func()) // If only one relationship exists between
                                  // Source and Destination.

Link(Source, Destination, Description)

Link(Source, Destination, Description, func())

Where Source and Destination are one of:

  • Person|"<Person>"
  • SoftwareSystem|"<Software System>"
  • Container
  • "<Container>" (if container is in the container or component view software system)
  • "<Software System/Container>"
  • Component
  • "<Component>" (if component is in the component view container)
  • "<Container>/<Component>" (if container is in the component view software system)
  • "<Software System>/<Container>/<Component>"

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.", func() {
        Container("Container")
        Container("Other Container", func() {
            Uses("Container", "Makes requests to")
        })
    })
    var Person = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    DeploymentEnvironment("Production", func() {
        DeploymentNode("Cloud", func() {
            ContainerInstance("Container")
            ContainerInstance("Container", func() {
                InstanceID(2)
            })
            ContainerInstance("Other Container")
        })
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram", func() {
            Add(System, func() {
                Coord(10, 10)
                NoRelationships()
            })
            Link(Person, System, "Sends emails", func() {
                Vertices(10, 20, 10, 40)
                Routing(RoutingOrthogonal)
                Position(45)
            })
        })
        DeploymentView(Global, "Production", "deployment", "A deployment view", func() {
            Add("Cloud/Container")
            Add("Cloud/Container/2")
            Add("Cloud/Other Container")
            Link("Cloud/Container", "Cloud/Other Container")
            Link("Cloud/Container/2", "Cloud/Other Container")
        })
        DynamicView(SoftwareSystem, "dynamic", func() {
            Title("Customer flow")
            Link(Person, System, "Sends emails", func() {
                Vertices(10, 20, 10, 40)
                Routing(RoutingOrthogonal)
                Position(45)
                Description("Customer sends email to support")
                Order("1")
            })
        })
    })
})

func NoRelationship

func NoRelationship()

NoRelationship indicates that no relationship should be rendered to and from the person or element.

NoRelationship must appear in Add.

NoRelationship takes no argument.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var OtherSystem = SoftwareSystem("Other software System")
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            Add(Customer, func() {
                NoRelationship()
            })
        })
    })
})

func NodeSeparation

func NodeSeparation(sep int)

NodeSeparation sets the separation between nodes in pixels, defaults to 600.

NodeSeparation must appear in AutoLayout.

NodeSeparation takes one argument: the node separation in pixels.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AutoLayout(func() {
                NodeSeparation(500)
            })
        })
    })
})

func Opacity

func Opacity(percent int)

Opacity sets elements or relationships opacity, default is 100.

Opacity must appear in ElementStyle or RelationshipStyle.

Opacity accepts a single argument: the opacity value between 0 (transparent) and 100 (opaque).

func PaperSize

func PaperSize(size PaperSizeKind)

PaperSize defines the paper size that should be used to render the view in the Structurizr service.

PaperSize must appear in SystemLandscapeView, SystemContextView, ContainerView, ComponentView, DynamicView or DeploymentView.

PaperSize accepts a single argument: the paper size. The possible values for the argument follow the patterns SizeA[0-6][Portrait|Landscape], SizeLetter[Portrait|Landscape] or SizeLegal[Portrait_Landscape]. Alternatively the argument may be one of SizeSlide4X3, SizeSlide16X9 or SizeSlide16X10.

Example

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var OtherSystem = SoftwareSystem("Other software System")
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddDefault()
            PaperSize(SizeSlide4X3)
        })
    })
})

func Person

func Person(name string, args ...any) *expr.Person

Person defines a person (user, actor, role or persona).

Person must appear in a Model expression.

Person takes one to three arguments. The first argument is the name of the person. An optional description may be passed as second argument. The last argument may be a function that defines tags associated with the Person.

The valid syntax for Person is thus:

Person("name")

Person("name", "description")

Person("name", func())

Person("name", "description", func())

Example:

var _ = Design(func() {
    Person("Employee")
    Person("Customer", "A customer", func() {
        Tag("system")
        External()
        URL("https://acme.com/docs/customer.html")
        Uses(System)
        InteractsWith(Employee)
    })
})

func Position

func Position(pos int)

Position sets the position of a relationship annotation along the line.

Position must appear in a Add expression that adds a relationship or in RelationshipStyle.

Position takes one argument: the position value between 0 (start of line) and 100 (end of line).

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            Add(Customer, System, func() {
                Position(40)
            })
        })
    })
})

func Prop

func Prop(name, value string)

Prop defines arbitrary key-value pairs. They are shown in the diagram tooltip and can be used to store metadata (e.g. team name).

Prop must appear in Person, SoftwareSystem, Container, Component, DeploymentNode, InfrastructureNode or ContainerInstance.

Prop accepts two arguments: the name and value of a property.

Example:

var _ = Design(func() {
    SoftwareSystem("MySystem", func() {
       Prop("name", "value")
    })
})

func RankSeparation

func RankSeparation(sep int)

RankSeparation sets the separation between ranks in pixels, defaults to 300.

RankSeparation must appear in AutoLayout.

RankSeparation takes one argument: the rank separation in pixels.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AutoLayout(func() {
                RankSeparation(500)
            })
        })
    })
})

func RelationshipStyle

func RelationshipStyle(tag string, dsl func())

RelationshipStyle defines relationship styles.

RelationshipStyle must appear in Styles.

RelationshipStyle accepts two arguments: the tag that identifies the relationships that the style should be applied to and a function describing the style properties.

Example:

var _ = Design(func() {
    // ...
    Views(func() {
        // ...
        Styles(func() {
            RelationshipStyle("default", func() {
                Thick()
                Color("#000000")
                Stroke("#000000")
                Solid()
                Routing(RoutingOrthogonal)
            })
        })
    })
})

func Remove

func Remove(element any)

Remove given person, software system, container or component from the view.

Remove must appear in SystemLandscapeView, SystemContextView, ContainerView or ComponentView.

Remove takes one argument: the element or the path to the element to be removed. The path consists of the element name if a top level element (person or software system) or if the element is in scope (container in container view software system, container in component view software system or component in component view container). When the element is not in scope the path specifies the parent element name followed by a slash and the element name. If the parent itself is not in scope (i.e. a component that is a child of a different software system in a ComponentView) then the path specifies the top-level software system followed by a slash, the container name, another slash and the component name.

Usage:

Remove(Person|"<Person>")

Remove(SoftwareSystem|"<Software System>")

Remove(Container)

Remove("<Container>") // if container is in scope

Remove("<Software System>/<Container>")

Remove(Component)

Remove("<Component>") // if component is in scope

Remove("<Container>/<Component>") // if container is in scope

Remove("<Software System>/<Container>/<Component>")

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.", func() {
        Container("Unwanted")
    })
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(System, "context", "An overview diagram.", func() {
            AddDefault()
            Remove(Customer)
            Remove("Unwanted")
        })
    })
})

func RemoveTagged added in v1.5.0

func RemoveTagged(tag string)

RemoveTagged removes all elements and relationships with the given tag from the view.

RemoveTagged must appear in SystemLandscapeView, SystemContextView, ContainerView or ComponentView.

Remove takes one argument: the tag identifying the elements and relationships to be removed.

Usage:

RemoveTagged("<tag>")

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.", func() {
        Container(System, "Unwanted", func() {
            Tag("irrelevant")
        })
    })
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP", func() {
            Tag("irrelevant")
        })
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddDefault()
            RemoveTagged("irrelevant")
        })
    })
})

func RemoveUnreachable

func RemoveUnreachable(element any)

RemoveUnreachable removes all elements and people that cannot be reached by traversing the graph of relationships starting with the given element or person.

RemoveUnreachable must appear in SystemLandscapeView, SystemContextView, ContainerView or ComponentView.

RemoveUnreachable accept a single argument which is the element used to start the graph traversal. The element is identified by reference or by path. The path consists of the element name if a top level element (person or software system) or if the element is in scope (container in container view software system, container in component view software system or component in component view container). When the element is not in scope the path specifies the parent element name followed by a slash and the element name. If the parent itself is not in scope (i.e. a component that is a child of a different software system in a ComponentView) then the path specifies the top-level software system followed by a slash, the container name, another slash and the component name.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var OtherSystem = SoftwareSystem("Other software System")
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddDefault()
            RemoveUnreachable(System) // Removes OtherSystem
        })
    })
})

func RemoveUnrelated

func RemoveUnrelated()

RemoveUnrelated removes all elements that have no relationship to other elements in the view.

RemoveUnrelated must appear in SystemLandscapeView, SystemContextView, ContainerView or ComponentView.

RemoveUnrelated takes no argument.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var OtherSystem = SoftwareSystem("Other software System")
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddDefault()
            RemoveUnrelated()) // Removes OtherSystem
        })
    })
})

func RenderVertices

func RenderVertices()

RenderVertices indicates that vertices should be created during automatic layout, false by default.

RenderVertices must appear in AutoLayout.

RenderVertices takes no argument.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AutoLayout(func() {
                RenderVertices()
            })
        })
    })
})

func Routing

func Routing(kind RoutingKind)

Routing algorithm used when rendering relationship, defaults to RoutingDirect.

Routing must appear in a Add expr.ssion that adds a relationship or in a RelationshipStyle expr.ssion.

Routing takes one argument: one of RoutingDirect, RoutingCurved or RoutingOrthogonal.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            Add(Customer, System, func() {
                Routing(RoutingDirect)
            })
        })
    })
})

func Shape

func Shape(kind ShapeKind)

Shape defines element shapes, default is ShapeBox.

Shape must apear in ElementStyle.

Shape accepts one argument, one of: ShapeBox, ShapeRoundedBox, ShapeCircle, ShapeEllipse, ShapeHexagon or ShapeCylinder, ShapePipe, ShapePerson ShapeRobot, ShapeFolder, ShapeWebBrowser, ShapeMobileDevicePortrait, ShapeMobileDeviceLandscape or ShapeComponent.

func ShowDescription

func ShowDescription()

ShowDescription shows the elements description.

ShowDescription must appear in ElementStyle.

ShowDescription takes no argument.

func ShowMetadata

func ShowMetadata()

ShowMetadata shows the elements metadata.

ShowMetadata must appear in ElementStyle.

ShowMetadata takes no argument.

func SoftwareSystem

func SoftwareSystem(name string, args ...any) *expr.SoftwareSystem

SoftwareSystem defines a software system.

SoftwareSystem must appear in a Design expression.

Software system takes 1 to 3 arguments. The first argument is the software system name and the last argument a function that contains the expressions that defines the content of the system. An optional description may be given after the name.

The valid syntax for SoftwareSystem is thus:

SoftwareSystem("<name>")

SoftwareSystem("<name>", "[description]")

SoftwareSystem("<name>", func())

SoftwareSystem("<name>", "[description]", func())

Example:

var _ = Design(func() {
    SoftwareSystem("My system", "A system with a great architecture", func() {
        Tag("bill processing")
        URL("https://goa.design/mysystem")
        External()
        Uses("Other System", "Uses", "gRPC", Synchronous)
        Delivers("Customer", "Delivers emails to", "SMTP", Synchronous)
    })
})

func Solid

func Solid()

Solid makes relationship lines solid (non-dashed).

Solid must appear in RelationshipStyle.

Solid takes no argument.

func Stroke

func Stroke(color string)

Stroke sets elements stroke color.

Stroke must appear in ElementStyle.

Stroke accepts a single argument: the background color encoded as HTML hex value (e.g. "#ffffff").

func Styles

func Styles(dsl func())

Styles is a wrapper for one or more element/relationship styles, which are used when rendering diagrams.

Styles must appear in Views.

Styles accepts a single argument: a function that defines the styles.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "Great system.", func() {
        Tag("blue")
    })

    var User = Person("User", "A user of my software system.", func() {
        Tag("blue", "person")
        Uses(System, "Uses", func() {
            Tag("client")
        })
    })

    Views(func() {
        SystemContext(MySystem, "SystemContext", "Context diagram.", func() {
            AddAll()
            AutoLayout(RankTopBottom)
        })
        Styles(func() {
            ElementStyle("blue", func() {
                Background("#1168bd")
                Color("#3333ee")
             })
            ElementStyle("person", func() {
                Shape("ShapePerson")
            })
            RelationshipStyle("client", func() {
                Routing(RoutingCurved)
                Thickness(42)
            })
        })
    })
})

func SystemBoundariesVisible

func SystemBoundariesVisible()

SystemBoundariesVisible makes the system boundaries visible for "external" containers (those outside the software system in scope)

SystemBoundariesVisible must appear in ContainerView.

SystemBoundariesVisible takes no argument

func SystemContextView

func SystemContextView(system any, key string, args ...any)

SystemContextView defines a system context view.

SystemContextView must appear in Views.

SystemContextView accepts 3 to 4 arguments: the first argument is the system or the name of the system the view applies to. The second argument is a unique key for the view which can be used to reference it when creating a fltered views. The third argument is an optional description. The last argument is a function describing the properties of the view.

Usage:

SystemContextView(SoftwareSystem, "<key>", func())

SystemContextView("<Software System>", "<key>", func())

SystemContextView(SoftwareSystem, "<key>", "[description]", func())

SystemContextView("<Software System>", "<key>", "[description]", func())

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var OtherSystem = SoftwareSystem("Other System")
    Views(func() {
        SystemContextView(System, "context", "An overview diagram.", func() {
            Title("Overview of system")
            AddAll()
            Remove(OtherSystem)
            AutoLayout(RankTopBottom)
            AnimationStep(System)
            PaperSize(SizeSlide4X3)
            EnterpriseBoundaryVisible()
        })
    })
})

func SystemLandscapeView

func SystemLandscapeView(key string, args ...any)

SystemLandscapeView defines a system landscape view.

SystemLandscapeView must appear in Views.

SystemLandscapeView accepts 2 to 3 arguments: the first argument is a unique key for the view which can be used to reference it when creating a filtered views. The second argument is an optional description. The last argument is a function describing the properties of the view.

Usage:

SystemLandscapeView("<key>", func())

SystemLandscapeView("<key>", "[description]", func())

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var OtherSystem = SoftwareSystem("Other System")
    Views(func() {
        SystemLandscapeView("landscape", "An overview diagram.", func() {
            Title("Overview of system")
            AddAll()
            Remove(OtherSystem)
            AutoLayout(RankTopBottom)
            AnimationStep(System)
            PaperSize(SizeSlide4X3)
            EnterpriseBoundaryVisible()
        })
    })
})

func Tag

func Tag(first string, t ...string)

Tag defines a set of tags on the given element. Tags are used in views to identify group of elements that should be rendered together for example.

Tag may appear in Person, SoftwareSystem, Container, Component, DeploymentNode, InfrastructureNode, ContainerInstance, Uses, InteractsWith or Delivers.

Tag accepts the set of tag values as argument. Tag may appear multiple times in the same expression in which case the tags accumulate.

Example:

var _ = Design(func() {
    System("My system", func() {
        Tag("sharded", "critical")
        Tag("blue team")
     })
})

func Thickness

func Thickness(pixels int)

Thickness sets relationships thickness.

Thickness must appear in RelationshipStyle.

Thickness takes one argument: the thickness in pixels.

func Timeout

func Timeout(n int)

Timeout defines a health check timeout in milliseconds.

Timeout must appear in a HealthCheck expression.

Timeout takes one argument: the number of milliseconds.

Example:

var _ = Design(func() {
    DeploymentEnvironment("Production", func() {
        ContainerInstance(Container, func() {
            HealthCheck("check", func() {
                Timeout(1000)
            })
        })
    })
})

func Title

func Title(t string)

Title sets the view diagram title.

Title may appear in SystemLandscapeView, SystemContextView, ContainerView, ComponentView, DynamicView or DeploymentView.

Title accepts one argument: the view title.

func URL

func URL(u string)

URL where more information about this element can be found. Or URL of health check when used within a HealthCheck expression.

URL may appear in Person, SoftwareSystem, Container, Component, DeploymentNode, InfrastructureNode or HealthCheck.

URL takes exactly one argument: a valid URL.

Example:

var _ = Design(func() {
    System("My system", func() {
        URL("https://goa.design/docs/mysystem")
    })
})
func Unlink(source, destination any, description ...string)

Unlink removes a relationship from a view.

Unlink must appear in SystemLandscapeView, SystemContextView, ContainerView or ComponentView.

Unlink takes the relationship as defined by its source, destination and when needed to distinguish its description.

The source and destination are identified by reference or by path. The path consists of the element name if a top level element (person or software system) or if the element is in scope (container in container view software system, container in component view software system or component in component view container). When the element is not in scope the path specifies the parent element name followed by a slash and the element name. If the parent itself is not in scope (i.e. a component that is a child of a different software system in a ComponentView) then the path specifies the top-level software system followed by a slash, the container name, another slash and the component name.

Usage:

Unlink(Source, Destination) // If only one relationship exists between
                            // Source and Destination
Unlink(Source, Destination, Description)

Where Source and Destination are one of:

  • Person|"<Person>"
  • SoftwareSystem|"<Software System>"
  • Container
  • "<Container>" (if container is in the container or component view software system)
  • "<Software System/Container>"
  • Component
  • "<Component>" (if component is in the component view container)
  • "<Container>/<Component>" (if container is in the component view software system)
  • "<Software System>/<Container>/<Component>"

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var Person = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            AddDefault()
            Unlink(Person, System, "Sends emails")
        })
    })
})

func Uses

func Uses(element any, description string, args ...any)

Uses adds a uni-directional relationship between two elements.

Uses may appear in Person, SoftwareSystem, Container or Component.

Uses takes 2 to 5 arguments. The first argument identifies the target of the relationship. The following argument is a short description for the relationship. The description may optionally be followed by the technology used by the relationship and/or the type of relationship: Synchronous or Asynchronous. Finally Uses accepts an optional func() as last argument to define additional properties on the relationship.

The target of the relationship is identified by providing an element (person, software system, container or component) or the path of an element. The path consists of the element name if a top level element (person or software system) or if the element is in scope (container in the same software system as the source or component in the same container as the source). When the element is not in scope the path specifies the parent element name followed by a slash and the element name. If the parent itself is not in scope (i.e. a component that is a child of a different software system than the source) then the path specifies the top-level software system followed by a slash, the container name, another slash and the component name.

Usage:

Uses(Element, "<description>")

Uses(Element, "<description>", "[technology]")

Uses(Element, "<description>", Synchronous|Asynchronous)

Uses(Element, "<description>", "[technology]", Synchronous|Asynchronous)

Uses(Element, "<description>", func())

Uses(Element, "<description>", "[technology]", func())

Uses(Element, "<description>", Synchronous|Asynchronous, func())

Uses(Element, "<description>", "[technology]", Synchronous|Asynchronous, func())

Where Element is one of:

  • Person, SoftwareSystem, Container or Component
  • "<Person>", "<SoftwareSystem>", "<SoftwareSystem>/<Container>" or "<SoftwareSystem>/<Container>/<Component>"
  • "<Container>" (if container is a sibling of the source)
  • "<Component>" (if component is a sibling of the source)
  • "<Container>/<Component>" (if container is a sibling of the source)

Example:

var _ = Design("my workspace", "a great architecture model", func() {
    SoftwareSystem("SystemA", func() {
        Container("ContainerA")
        Container("ContainerB", func() {
            Uses("ContainerA") // sibling, not need to specify system
        })
    })
    SoftwareSystem("SystemB", func() {
        Uses("SystemA/ContainerA") // not a sibling, need full path
    })
    Person("Customer", "Customers of enterprise", func () {
       Uses(SystemA, "Access", "HTTP", Synchronous)
    })
    Person("Staff", "Back office staff", func() {
       InteractsWith("Customer", "Sends invoices to", Synchronous)
    })
})

func Version

func Version(v string)

Version specifies a version number for the design.

Version must appear in a Design expression.

Version takes exactly one argument: the version number.

Example:

var _ = Design(func() {
    Version("1.0")
})

func Vertices

func Vertices(args ...int)

Vertices lists the x and y coordinate of the vertices used to render the relationship.

Vertices must appear in Add when adding relationships.

Vertices takes the x and y coordinates of the vertices as argument. The number of arguments must be even.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    var Customer = Person("Customer", func() {
        External()
        Uses(System, "Sends emails", "SMTP")
    })
    Views(func() {
        SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
            Link(Customer, System, func() {
                Vertices(300, 100, 400, 200)
            })
        })
    })
})

func Views

func Views(dsl func())

Views defines one or more views.

Views takes one argument: the function that defines the views.

Views must appear in Design.

Example:

var _ = Design(func() {
    var System = SoftwareSystem("Software System", "My software system.")
    Views(func() {
        SystemContext(System, "SystemContext", "An example of a System Context diagram.", func() {
            AddAll()
            AutoLayout(RankTopBottom)
        })
    })
})

func Width

func Width(width int)

Width sets elements or a relationships width, default is 450.

Width must appear in ElementStyle or RelationshipStyle.

Width accepts a single argument: the width in pixel.

Types

type BorderKind added in v1.6.0

type BorderKind int

BorderKind is the enum used to represent element border styles.

const (
	BorderSolid BorderKind = iota + 1
	BorderDashed
	BorderDotted
)

type ImplementationKind added in v1.9.1

type ImplementationKind int

ImplementationKind is the enum for possible automatic layout implementations

const (
	// ImplementationGraphviz indicates the automatic layout will be using Graphviz
	ImplementationGraphviz ImplementationKind = iota + 1
	// ImplementationDagre indicates the automatic layout will be using Dagre
	ImplementationDagre
)

type InteractionStyleKind added in v1.6.0

type InteractionStyleKind int

InteractionStyleKind is the enum for possible interaction styles.

const (
	// Synchronous describes a synchronous interaction.
	Synchronous InteractionStyleKind = iota + 1
	// Asynchronous describes an asynchronous interaction.
	Asynchronous
)

type PaperSizeKind added in v1.6.0

type PaperSizeKind int

PaperSizeKind is the enum for possible paper kinds.

const (
	// SizeA0Landscape defines a render page size of A0 in landscape mode (46-13/16 x 33-1/8).
	SizeA0Landscape PaperSizeKind = iota + 1
	// SizeA0Portrait defines a render page size of A0 in portrait mode (33-1/8 x 46-13/16).
	SizeA0Portrait
	// SizeA1Landscape defines a render page size of A1 in landscape mode (33-1/8 x 23-3/8).
	SizeA1Landscape
	// SizeA1Portrait defines a render page size of A1 in portrait mode (23-3/8 x 33-1/8).
	SizeA1Portrait
	// SizeA2Landscape defines a render page size of A2 in landscape mode (23-3/8 x 16-1/2).
	SizeA2Landscape
	// SizeA2Portrait defines a render page size of A2 in portrait mode (16-1/2 x 23-3/8).
	SizeA2Portrait
	// SizeA3Landscape defines a render page size of A3 in landscape mode (16-1/2 x 11-3/4).
	SizeA3Landscape
	// SizeA3Portrait defines a render page size of A3 in portrait mode (11-3/4 x 16-1/2).
	SizeA3Portrait
	// SizeA4Landscape defines a render page size of A4 in landscape mode (11-3/4 x 8-1/4).
	SizeA4Landscape
	// SizeA4Portrait defines a render page size of A4 in portrait mode (8-1/4 x 11-3/4).
	SizeA4Portrait
	// SizeA5Landscape defines a render page size of A5 in landscape mode (8-1/4  x 5-7/8).
	SizeA5Landscape
	// SizeA5Portrait defines a render page size of A5 in portrait mode (5-7/8 x 8-1/4).
	SizeA5Portrait
	// SizeA6Landscape defines a render page size of A6 in landscape mode (4-1/8 x 5-7/8).
	SizeA6Landscape
	// SizeA6Portrait defines a render page size of A6 in portrait mode (5-7/8 x 4-1/8).
	SizeA6Portrait
	// SizeLegalLandscape defines a render page size of Legal in landscape mode (14 x 8-1/2).
	SizeLegalLandscape
	// SizeLegalPortrait defines a render page size of Legal in portrait mode (8-1/2 x 14).
	SizeLegalPortrait
	// SizeLetterLandscape defines a render page size of Letter in landscape mode (11 x 8-1/2).
	SizeLetterLandscape
	// SizeLetterPortrait defines a render page size of Letter in portrait mode (8-1/2 x 11).
	SizeLetterPortrait
	// SizeSlide16X10 defines a render page size ratio of 16 x 10.
	SizeSlide16X10
	// SizeSlide16X9 defines a render page size ratio of 16 x 9.
	SizeSlide16X9
	// SizeSlide4X3 defines a render page size ratio of 4 x 3.
	SizeSlide4X3
)

type RankDirectionKind added in v1.6.0

type RankDirectionKind int

RankDirectionKind is the enum for possible automatic layout rank directions.

const (
	// RankTopBottom indicates a layout that uses top to bottom rank.
	RankTopBottom RankDirectionKind = iota + 1
	// RankBottomTop indicates a layout that uses bottom to top rank.
	RankBottomTop
	// RankLeftRight indicates a layout that uses left to right rank.
	RankLeftRight
	// RankRightLeft indicates a layout that uses right to left rank.
	RankRightLeft
)

type RoutingKind added in v1.6.0

type RoutingKind int

RoutingKind is the enum for possible routing algorithms.

const (
	// RoutingDirect draws straight lines between ends of relationships.
	RoutingDirect RoutingKind = iota + 1
	// RoutingOrthogonal draws lines with right angles between ends of relationships.
	RoutingOrthogonal
	// RoutingCurved draws curved lines between ends of relationships.
	RoutingCurved
)

type ShapeKind added in v1.6.0

type ShapeKind int

ShapeKind is the enum used to represent element shapes.

const (
	// Shapes allowed in ElementStyle
	ShapeBox ShapeKind = iota + 1
	ShapeCircle
	ShapeCylinder
	ShapeEllipse
	ShapeHexagon
	ShapeRoundedBox
	ShapeComponent
	ShapeFolder
	ShapeMobileDeviceLandscape
	ShapeMobileDevicePortrait
	ShapePerson
	ShapePipe
	ShapeRobot
	ShapeWebBrowser
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL