Skip to content

Port Interface Reference

Complete reference for port definitions in TinySystems components.

Port Structure

go
type Port struct {
    Name          string      // Unique identifier
    Label         string      // Display label
    Position      Position    // Visual position
    Source        bool        // Direction (input/output)
    Configuration interface{} // Schema struct
}

Fields

Name

Unique identifier for the port within the component.

Type: string

Requirements:

  • Must be unique within the component
  • Use lowercase with hyphens or underscores
  • Avoid special characters

Reserved Names:

NamePurpose
_settingsComponent settings
_controlControl port (buttons)
_reconcileReconciliation events
_clientResource manager access

Examples:

go
Name: "input"
Name: "output"
Name: "out_success"
Name: "out_error"
Name: "request"
Name: "response"

Label

Human-readable display label for the UI.

Type: string

Guidelines:

  • Use title case
  • Keep concise (1-3 words)
  • Describe the port's purpose

Examples:

go
Label: "Input"
Label: "Output"
Label: "Settings"
Label: "HTTP Request"
Label: "Success"
Label: "Error"

Position

Visual position on the node in the flow editor.

Type: module.Position

Values:

ConstantValueTypical Use
PositionLeft"left"Input ports
PositionRight"right"Output ports
PositionTop"top"Settings, Control
PositionBottom"bottom"Errors, Status

Visual Layout:

            ⬆️ Top (Settings, Control)

   Left ◀️ ─┼─ ▶️ Right

            ⬇️ Bottom (Errors, Status)

Best Practices:

  • Input ports on the left
  • Output ports on the right
  • Settings/control on top
  • Errors/status on bottom

Source

Indicates port direction.

Type: bool

Values:

ValueDirectionDescription
trueInputReceives messages
falseOutputEmits messages

Note: The naming is counterintuitive - Source: true means the port is a "source" of messages into the component (input port).

Examples:

go
// Input port
Source: true

// Output port
Source: false

Configuration

Struct that defines the port's schema and default values.

Type: interface{}

Purpose:

  • Defines the JSON Schema for the port
  • Provides default values
  • Configures UI rendering

Example:

go
Configuration: struct {
    UserID   string `json:"userId" required:"true" title:"User ID"`
    Email    string `json:"email" format:"email" title:"Email"`
    Age      int    `json:"age" minimum:"0" maximum:"150"`
    Active   bool   `json:"active" default:"true"`
}{}

Position Constants

go
const (
    PositionLeft   Position = "left"
    PositionRight  Position = "right"
    PositionTop    Position = "top"
    PositionBottom Position = "bottom"
)

Common Port Patterns

Settings Port

go
{
    Name:          v1alpha1.SettingsPort,
    Label:         "Settings",
    Position:      module.PositionTop,
    Source:        true,
    Configuration: Settings{
        Timeout:    "30s",
        MaxRetries: 3,
    },
}

Simple Input/Output

go
// Input
{
    Name:          "input",
    Label:         "Input",
    Position:      module.PositionLeft,
    Source:        true,
    Configuration: Input{},
}

// Output
{
    Name:          "output",
    Label:         "Output",
    Position:      module.PositionRight,
    Source:        false,
    Configuration: Output{},
}

Multiple Outputs

go
{
    Name:          "out_success",
    Label:         "Success",
    Position:      module.PositionRight,
    Source:        false,
    Configuration: SuccessOutput{},
},
{
    Name:          "out_error",
    Label:         "Error",
    Position:      module.PositionBottom,
    Source:        false,
    Configuration: ErrorOutput{},
}

Control Port

go
{
    Name:          v1alpha1.ControlPort,
    Label:         "Control",
    Position:      module.PositionTop,
    Source:        true,
    Configuration: ControlState{
        Status:   "stopped",
        Start:    false,
        Stop:     false,
    },
}

HTTP Server Ports

go
// Request output (emits incoming requests)
{
    Name:          "request",
    Label:         "Request",
    Position:      module.PositionRight,
    Source:        false,
    Configuration: HTTPRequest{},
},
// Response input (receives responses to send)
{
    Name:          "response",
    Label:         "Response",
    Position:      module.PositionLeft,
    Source:        true,
    Configuration: HTTPResponse{},
}

Dynamic Ports

Ports can be generated dynamically based on configuration.

Example: Router with Dynamic Routes

go
func (c *Router) Ports() []module.Port {
    ports := []module.Port{
        {
            Name:          v1alpha1.SettingsPort,
            Label:         "Settings",
            Position:      module.PositionTop,
            Source:        true,
            Configuration: Settings{},
        },
        {
            Name:          "input",
            Label:         "Input",
            Position:      module.PositionLeft,
            Source:        true,
            Configuration: Input{},
        },
    }

    // Add dynamic output ports based on routes
    for _, route := range c.settings.Routes {
        ports = append(ports, module.Port{
            Name:          "out_" + route.Name,
            Label:         route.Label,
            Position:      module.PositionRight,
            Source:        false,
            Configuration: Output{},
        })
    }

    // Always include default route
    ports = append(ports, module.Port{
        Name:          "out_default",
        Label:         "Default",
        Position:      module.PositionRight,
        Source:        false,
        Configuration: Output{},
    })

    return ports
}

Schema Configuration

The Configuration field uses struct tags to define JSON Schema:

go
Configuration: struct {
    // Basic types
    StringField  string  `json:"stringField" title:"String Field"`
    IntField     int     `json:"intField" title:"Integer Field"`
    FloatField   float64 `json:"floatField" title:"Float Field"`
    BoolField    bool    `json:"boolField" title:"Boolean Field"`

    // Validation
    Required string `json:"required" required:"true"`
    MinMax   int    `json:"minMax" minimum:"0" maximum:"100"`
    Pattern  string `json:"pattern" pattern:"^[a-z]+$"`

    // UI hints
    Textarea   string `json:"textarea" format:"textarea"`
    Password   string `json:"password" format:"password"`
    Email      string `json:"email" format:"email"`

    // Defaults
    WithDefault string `json:"withDefault" default:"hello"`
}{}

Port Validation

At Component Load

TinySystems validates ports when loading a component:

  • Unique port names
  • Valid position values
  • Schema generation succeeds

At Runtime

When processing messages:

  • Message type matches expected schema
  • Required fields are present
  • Validation rules pass

Best Practices

1. Consistent Naming

go
// Good
"input", "output", "settings"
"out_success", "out_error"
"request", "response"

// Avoid
"Input1", "OUTPUT", "my port"

2. Clear Labels

go
// Good
Label: "HTTP Request"
Label: "Processed Output"

// Avoid
Label: "out"
Label: "data"

3. Logical Positioning

go
// Inputs on left
Position: module.PositionLeft

// Outputs on right
Position: module.PositionRight

// Errors on bottom
Position: module.PositionBottom

4. Meaningful Defaults

go
Configuration: Settings{
    Timeout:    "30s",    // Sensible default
    MaxRetries: 3,        // Common value
    Enabled:    true,     // Typical starting state
}

5. Complete Schemas

go
Configuration: Input{
    UserID string `json:"userId" required:"true" title:"User ID" description:"Unique user identifier"`
}

Build flow-based applications on Kubernetes