Schema Form
Render a complete generated form surface for config-driven UIs. Walk a JSON Schema object-keyword subset, merge defaults with current submitted values, apply allow-list rules, then host the generated fields inside your own form.
Container image version.
Number of pods to run.
Kubernetes Service exposure mode.
Managed by the platform catalog.
Terminate HTTPS at the service edge.
schema := map[string]any{
"$schema": "https://json-schema.org/draft/2020-12/schema", // optional; ignored by Walk
"properties": map[string]any{
"replicaCount": map[string]any{"type": "integer", "title": "Replica count"},
"imageTag": map[string]any{"type": "string", "title": "Image tag"},
"tlsEnabled": map[string]any{"type": "boolean", "title": "TLS enabled"},
"serviceType": map[string]any{"enum": []any{"ClusterIP", "LoadBalancer", "NodePort"}},
"teamOwner": map[string]any{"type": "string", "title": "Team owner"},
"internalToken": map[string]any{"type": "string", "title": "Internal token"},
},
}
defaults := map[string]any{
"replicaCount": 3,
"serviceType": "ClusterIP",
"teamOwner": "platform",
}
values := map[string]any{
// Current submitted values override defaults when the form re-renders.
"serviceType": "LoadBalancer",
}
allowList := map[string]schemaform.AllowMode{
"teamOwner": schemaform.AllowModeManaged,
"internalToken": schemaform.AllowModeDisabled,
}
fields := schemaform.Walk(schema, defaults, values, allowList)
@form.Form(form.Config{ID: "config-form", Method: "post"}) {
@schemaform.Fields(schemaform.FieldsConfig{
Fields: fields,
NamePrefix: "values",
})
}Schema Subset And Version
Schema Form is a renderer, not a JSON Schema validator. Walk accepts map[string]any decoded from JSON Schema and ignores $schema, so no draft version is required. The supported keywords are the stable object/form subset shared by Draft 7, 2019-09, and 2020-12: properties, nested properties, required, type, title, description, enum, and scalar-array items.
Input schema
JSON Schema object subset decoded into map[string]any.
Version handling
$schema is optional and ignored; supported keywords are draft-stable.
Rendered keywords
properties, required, type, title, description, enum, and scalar-array items.
// Walk consumes a JSON Schema object-keyword subset. It does not validate
// against a draft and does not require or inspect "$schema".
schema := map[string]any{
"$schema": "https://json-schema.org/draft/2020-12/schema", // optional metadata
"required": []any{"replicaCount"},
"properties": map[string]any{
"replicaCount": map[string]any{
"type": "integer",
"title": "Replica count",
"description": "Number of pods to run.",
},
"serviceType": map[string]any{
"enum": []any{"ClusterIP", "LoadBalancer", "NodePort"},
},
"zones": map[string]any{
"type": "array",
"items": map[string]any{"type": "string"},
},
},
}
fields := schemaform.Walk(schema, defaults, values, allowList)Allow-List Rules
Missing allow-list paths stay editable. Managed paths remain visible but disabled and marked as managed. Disabled paths are omitted entirely.
Editable
replicaCount is not listed, so users can change it.
Managed
teamOwner stays visible, disabled, and marked managed.
Disabled
internalToken is hidden and must be pruned before save.
allowList := map[string]schemaform.AllowMode{
// Missing paths are unmanaged and editable.
"teamOwner": schemaform.AllowModeManaged, // visible, disabled, managed badge
"internalToken": schemaform.AllowModeDisabled, // hidden entirely
}
fields := schemaform.Walk(schema, defaults, values, allowList)Fallback Form From Defaults
Use FallbackFromDefaults when a system publishes defaults but no JSON Schema. It preserves the same allow-list behavior while inferring controls from the default value shape.
defaults := map[string]any{
"resources": map[string]any{
"cpu": "500m",
"memory": "512Mi",
},
"zones": []any{"us-east-1a", "us-east-1b"},
"debug": false,
}
allowList := map[string]schemaform.AllowMode{
"resources.cpu": schemaform.AllowModeManaged,
}
fields := schemaform.FallbackFromDefaults(defaults, values, allowList)Submit And Prune
Submitted values win when you re-render after validation errors. Before serializing accepted config, prune disabled paths so hidden policy-owned values cannot be posted back.
// Names post as values.replicaCount and values.resources.cpu.
posted := map[string]any{
"replicaCount": 5,
"resources": map[string]any{"cpu": "900m", "memory": "1Gi"},
"internalToken": "should-not-be-saved",
}
// Re-render with posted values after validation errors.
fields := schemaform.Walk(schema, defaults, posted, allowList)
// Before save, remove hidden policy-owned values.
schemaform.PruneDisabled(posted, allowList)
saveConfig(posted)API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
Fields | []Field | nil | Ordered form controls produced by Walk or FallbackFromDefaults. |
NamePrefix | string | "values" | Prefix applied to generated input names, such as values.replicaCount. |
Walk | func | - | Builds fields from a draft-agnostic JSON Schema object subset, defaults, current values, and allow-list modes. |
FallbackFromDefaults | func | - | Infers a form from default values when no JSON Schema is available. |
FlattenAllowList | func | - | Converts nested allow_list data into dotted paths with managed or disabled modes. |
PruneDisabled | func | - | Removes disabled paths from values before serializing or submitting configuration. |
Field.Path | string | "" | Dotted config path used for generated names and allow-list matching. |
Field.Label | string | "" | Display label, usually sourced from schema title or the path segment. |
Field.HelperText | string | "" | Supporting copy, usually sourced from schema description. |
Field.Kind | Kind | - | Generated control kind: string, number, integer, boolean, enum, array, object, or unknown fallback. |
Field.Managed | bool | false | Marks visible read-only fields produced by AllowModeManaged. |
Field.Default / Field.Value | string | "" | Serialized default and current values; current submitted values override defaults on re-render. |
Field.Children | []Field | nil | Nested object fields; single-child objects unwrap into the child control. |
AllowModeManaged | AllowMode | - | Visible but disabled/read-only with a managed badge. |
AllowModeDisabled | AllowMode | - | Hidden entirely; prune the same path before saving posted values. |