Skip to content

Defining Ports

Ports are the connection points of your component. They define what data your component can receive and send.

Port Structure

go
type Port struct {
    Name          string         // Unique identifier
    Label         string         // Display name in UI
    Source        bool           // true = input, false = output
    Position      Position       // Left, Right, Top, Bottom
    Schema        schema.Schema  // Data structure definition
    Configuration Configuration  // Additional settings
    Status        Status         // Runtime status
}

Basic Port Definition

go
func (c *MyComponent) Ports() []module.Port {
    return []module.Port{
        // Input port
        {
            Name:     "input",
            Label:    "Input",
            Source:   true,
            Position: module.PositionLeft,
            Schema:   schema.FromGo(InputMessage{}),
        },
        // Output port
        {
            Name:     "output",
            Label:    "Output",
            Source:   false,
            Position: module.PositionRight,
            Schema:   schema.FromGo(OutputMessage{}),
        },
    }
}

Port Positions

                    PositionTop

          ┌─────────────┴─────────────┐
          │                           │
          │                           │
PositionLeft       Component        PositionRight
          │                           │
          │                           │
          └─────────────┬─────────────┘

                  PositionBottom
PositionConstantTypical Use
Leftmodule.PositionLeftInput ports (data flowing in)
Rightmodule.PositionRightOutput ports (data flowing out)
Topmodule.PositionTopControl inputs, settings
Bottommodule.PositionBottomError outputs, status

Port Types

Input Ports (Source = true)

Input ports receive data from other components:

go
{
    Name:     "request",
    Label:    "Request",
    Source:   true,  // This is an input
    Position: module.PositionLeft,
    Schema:   schema.FromGo(Request{}),
}

Output Ports (Source = false)

Output ports send data to connected components:

go
{
    Name:     "response",
    Label:    "Response",
    Source:   false,  // This is an output
    Position: module.PositionRight,
    Schema:   schema.FromGo(Response{}),
}

Schema Definition

Ports use JSON Schema for data validation. The schema.FromGo() function generates schemas from Go structs:

go
type Request struct {
    Method string            `json:"method" title:"HTTP Method" enum:"GET,POST,PUT,DELETE"`
    URL    string            `json:"url" title:"URL" format:"uri" required:"true"`
    Body   any               `json:"body,omitempty" title:"Request Body"`
}

// In Ports()
Schema: schema.FromGo(Request{})

Schema Tags

TagDescriptionExample
jsonJSON field namejson:"fieldName"
titleHuman-readable labeltitle:"Field Name"
descriptionHelp textdescription:"Enter the value"
requiredMark as requiredrequired:"true"
enumAllowed valuesenum:"a,b,c"
formatValidation formatformat:"email"
defaultDefault valuedefault:"hello"
minLengthMinimum string lengthminLength:"1"
maxLengthMaximum string lengthmaxLength:"100"
minimumMinimum numberminimum:"0"
maximumMaximum numbermaximum:"100"

Format Values

FormatValidates
emailEmail addresses
uriURLs
uri-referenceRelative URLs
dateISO date (YYYY-MM-DD)
date-timeISO datetime
timeISO time
durationISO duration
ipv4IPv4 addresses
ipv6IPv6 addresses
uuidUUIDs
regexRegular expressions

Multiple Ports Example

go
func (c *Router) Ports() []module.Port {
    return []module.Port{
        // Single input
        {
            Name:     "input",
            Label:    "Input",
            Source:   true,
            Position: module.PositionLeft,
            Schema:   schema.FromGo(Message{}),
        },
        // Multiple outputs
        {
            Name:     "route_a",
            Label:    "Route A",
            Source:   false,
            Position: module.PositionRight,
            Schema:   schema.FromGo(Message{}),
        },
        {
            Name:     "route_b",
            Label:    "Route B",
            Source:   false,
            Position: module.PositionRight,
            Schema:   schema.FromGo(Message{}),
        },
        {
            Name:     "default",
            Label:    "Default",
            Source:   false,
            Position: module.PositionBottom,
            Schema:   schema.FromGo(Message{}),
        },
    }
}

Port Configuration

Additional configuration options for ports:

go
{
    Name:   "settings",
    Label:  "Settings",
    Source: true,
    Configuration: module.Configuration{
        Async:        true,   // Don't wait for completion
        ArrayItemKey: "id",   // Key for array deduplication
        SchemaSource: "data", // Source for dynamic schema
    },
}
FieldDescription
AsyncMessage handling doesn't block sender
ArrayItemKeyField used to identify array items
SchemaSourceField containing dynamic schema

Dynamic Ports

Ports can be generated dynamically based on settings:

go
type Router struct {
    settings Settings
}

type Settings struct {
    Routes []string `json:"routes" title:"Route Names"`
}

func (r *Router) Ports() []module.Port {
    ports := []module.Port{
        {
            Name:     "input",
            Label:    "Input",
            Source:   true,
            Position: module.PositionLeft,
            Schema:   schema.FromGo(Message{}),
        },
    }

    // Generate output ports based on settings
    for _, route := range r.settings.Routes {
        ports = append(ports, module.Port{
            Name:     route,
            Label:    route,
            Source:   false,
            Position: module.PositionRight,
            Schema:   schema.FromGo(Message{}),
        })
    }

    return ports
}

Port Status

Runtime status information for ports:

go
{
    Name:   "server",
    Label:  "Server",
    Source: true,
    Status: module.Status{
        Label:       "Listening",
        Description: "Port 8080",
        State:       module.StateRunning,
    },
}
StateDescription
StateIdleNot active
StateRunningActive/running
StateErrorError condition

Common Port Patterns

Request/Response

go
func (c *HTTPClient) Ports() []module.Port {
    return []module.Port{
        {
            Name:     "request",
            Label:    "Request",
            Source:   true,
            Position: module.PositionLeft,
            Schema:   schema.FromGo(HTTPRequest{}),
        },
        {
            Name:     "response",
            Label:    "Response",
            Source:   false,
            Position: module.PositionRight,
            Schema:   schema.FromGo(HTTPResponse{}),
        },
        {
            Name:     "error",
            Label:    "Error",
            Source:   false,
            Position: module.PositionBottom,
            Schema:   schema.FromGo(HTTPError{}),
        },
    }
}

Filter/Split

go
func (c *Filter) Ports() []module.Port {
    return []module.Port{
        {
            Name:     "input",
            Label:    "Input",
            Source:   true,
            Position: module.PositionLeft,
            Schema:   schema.FromGo(Item{}),
        },
        {
            Name:     "match",
            Label:    "Match",
            Source:   false,
            Position: module.PositionRight,
            Schema:   schema.FromGo(Item{}),
        },
        {
            Name:     "no_match",
            Label:    "No Match",
            Source:   false,
            Position: module.PositionBottom,
            Schema:   schema.FromGo(Item{}),
        },
    }
}

Aggregator

go
func (c *Aggregator) Ports() []module.Port {
    return []module.Port{
        {
            Name:     "item",
            Label:    "Item",
            Source:   true,
            Position: module.PositionLeft,
            Schema:   schema.FromGo(Item{}),
        },
        {
            Name:     "flush",
            Label:    "Flush",
            Source:   true,
            Position: module.PositionTop,
            Schema:   schema.FromGo(FlushSignal{}),
        },
        {
            Name:     "batch",
            Label:    "Batch",
            Source:   false,
            Position: module.PositionRight,
            Schema:   schema.FromGo(Batch{}),
        },
    }
}

Next Steps

Build flow-based applications on Kubernetes