Skip to content

Schema from Go

The TinySystems SDK automatically generates JSON Schemas from Go structs. This makes defining port data structures simple and type-safe.

Basic Usage

go
import "github.com/tiny-systems/module/pkg/schema"

type Request struct {
    Method string `json:"method"`
    URL    string `json:"url"`
}

// Generate schema
sch := schema.FromGo(Request{})

Struct Tags

JSON Tag

The json tag defines the field name in JSON:

go
type User struct {
    FirstName string `json:"firstName"`  // camelCase in JSON
    LastName  string `json:"lastName"`
    Email     string `json:"email"`
}

Omitempty

Optional fields use omitempty:

go
type Request struct {
    URL     string `json:"url"`               // Required in schema
    Headers any    `json:"headers,omitempty"` // Optional
}

Title and Description

go
type Settings struct {
    Timeout int    `json:"timeout" title:"Timeout (ms)" description:"Request timeout in milliseconds"`
    Retries int    `json:"retries" title:"Retry Count" description:"Number of retry attempts"`
}

Type Mappings

Basic Types

Go TypeJSON Schema Type
string"type": "string"
int, int32, int64"type": "integer"
float32, float64"type": "number"
bool"type": "boolean"
[]T"type": "array"
struct"type": "object"
any, interface{}No type constraint
map[string]T"type": "object" with additionalProperties

Examples

go
type AllTypes struct {
    Text     string             `json:"text"`     // string
    Count    int                `json:"count"`    // integer
    Amount   float64            `json:"amount"`   // number
    Enabled  bool               `json:"enabled"`  // boolean
    Items    []string           `json:"items"`    // array of strings
    Metadata map[string]string  `json:"metadata"` // object with string values
    Data     any                `json:"data"`     // any type
}

Validation Tags

String Validation

go
type Input struct {
    Name     string `json:"name" minLength:"1" maxLength:"100"`
    Email    string `json:"email" format:"email"`
    Pattern  string `json:"pattern" pattern:"^[a-z]+$"`
}

Number Validation

go
type Config struct {
    Port     int     `json:"port" minimum:"1" maximum:"65535"`
    Timeout  float64 `json:"timeout" minimum:"0.1" maximum:"30"`
    Attempts int     `json:"attempts" minimum:"1" maximum:"10"`
}

Array Validation

go
type Batch struct {
    Items []Item `json:"items" minItems:"1" maxItems:"100"`
}

Enum Values

Simple Enum

go
type Request struct {
    Method string `json:"method" enum:"GET,POST,PUT,DELETE"`
}

Enum with Titles

go
type Config struct {
    Level string `json:"level" enum:"debug,info,warn,error" enumTitles:"Debug,Info,Warning,Error"`
}

Default Values

go
type Settings struct {
    Host    string `json:"host" default:"localhost"`
    Port    int    `json:"port" default:"8080"`
    Timeout int    `json:"timeout" default:"30000"`
    Enabled bool   `json:"enabled" default:"true"`
}

Required Fields

go
type User struct {
    ID    string `json:"id" required:"true"`
    Name  string `json:"name" required:"true"`
    Email string `json:"email,omitempty"` // Optional
}

Nested Structures

go
type ServerConfig struct {
    Host string `json:"host" title:"Server Host" default:"localhost"`
    Port int    `json:"port" title:"Server Port" default:"8080"`
}

type AuthConfig struct {
    Username string `json:"username" title:"Username" required:"true"`
    Password string `json:"password" title:"Password" format:"password" required:"true"`
}

type Settings struct {
    Server ServerConfig `json:"server" title:"Server Configuration"`
    Auth   AuthConfig   `json:"auth" title:"Authentication"`
}

// Usage
schema.FromGo(Settings{})

Embedded Structures

go
type BaseSettings struct {
    Enabled bool   `json:"enabled" default:"true"`
    Name    string `json:"name"`
}

type ExtendedSettings struct {
    BaseSettings        // Embedded - fields appear at top level
    CustomField string `json:"customField"`
}

Pointer Types

Pointers indicate optional fields:

go
type Message struct {
    ID      string  `json:"id"`       // Required
    Data    *Data   `json:"data"`     // Optional object
    Count   *int    `json:"count"`    // Optional integer
}

Arrays

Array of Primitives

go
type Tags struct {
    Names []string `json:"names" title:"Tag Names"`
}

Array of Objects

go
type Endpoint struct {
    Name string `json:"name" required:"true"`
    URL  string `json:"url" format:"uri" required:"true"`
}

type Settings struct {
    Endpoints []Endpoint `json:"endpoints" title:"API Endpoints" minItems:"1"`
}

Maps

String Map

go
type Config struct {
    Headers map[string]string `json:"headers" title:"HTTP Headers"`
}

Any Map

go
type Metadata struct {
    Properties map[string]any `json:"properties" title:"Custom Properties"`
}

Format Tags

go
type Input struct {
    Email    string `json:"email" format:"email"`
    Website  string `json:"website" format:"uri"`
    Date     string `json:"date" format:"date"`
    Time     string `json:"time" format:"time"`
    DateTime string `json:"dateTime" format:"date-time"`
    UUID     string `json:"uuid" format:"uuid"`
    IPv4     string `json:"ipv4" format:"ipv4"`
    IPv6     string `json:"ipv6" format:"ipv6"`
    Password string `json:"password" format:"password"`
}

UI Widget Tags

go
type Settings struct {
    Code        string `json:"code" widget:"code"`
    Description string `json:"description" widget:"textarea"`
}

Property Order

Control field display order:

go
type Form struct {
    Name  string `json:"name" propertyOrder:"1"`
    Email string `json:"email" propertyOrder:"2"`
    Bio   string `json:"bio" propertyOrder:"3"`
}

Complete Example

go
package mycomponent

import (
    "github.com/tiny-systems/module/module"
    "github.com/tiny-systems/module/pkg/schema"
)

type HTTPRequest struct {
    Method  string            `json:"method" title:"HTTP Method" enum:"GET,POST,PUT,DELETE" default:"GET"`
    URL     string            `json:"url" title:"URL" format:"uri" required:"true"`
    Headers map[string]string `json:"headers,omitempty" title:"Headers"`
    Body    any               `json:"body,omitempty" title:"Request Body"`
    Timeout int               `json:"timeout" title:"Timeout (ms)" default:"30000" minimum:"100" maximum:"300000"`
}

type HTTPResponse struct {
    StatusCode int               `json:"statusCode" title:"Status Code"`
    Headers    map[string]string `json:"headers" title:"Response Headers"`
    Body       any               `json:"body" title:"Response Body"`
}

type ErrorOutput struct {
    Error   string      `json:"error" title:"Error Message"`
    Request HTTPRequest `json:"request" title:"Original Request"`
}

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(ErrorOutput{}),
        },
    }
}

Tag Reference

TagDescriptionExample
jsonJSON field namejson:"fieldName"
titleDisplay labeltitle:"Field Name"
descriptionHelp textdescription:"Enter value"
defaultDefault valuedefault:"value"
requiredRequired fieldrequired:"true"
enumAllowed valuesenum:"a,b,c"
enumTitlesDisplay namesenumTitles:"A,B,C"
formatValidation formatformat:"email"
minimumMin numberminimum:"0"
maximumMax numbermaximum:"100"
minLengthMin string lengthminLength:"1"
maxLengthMax string lengthmaxLength:"100"
minItemsMin array lengthminItems:"1"
maxItemsMax array lengthmaxItems:"10"
patternRegex patternpattern:"^[a-z]+$"
propertyOrderDisplay orderpropertyOrder:"1"
widgetUI widgetwidget:"textarea"

Next Steps

Build flow-based applications on Kubernetes