Skip to main content
Version: Next

Parameter Chain Methods

Every parameter constructor — String, Int, Bool, Float, Enum, Array, Map, Object, StringKeyMap — returns a typed pointer that can be chained with constraint, metadata, and expression methods before being passed to .Params(). This document covers the full chain-method surface: common metadata and presence modifiers shared by all parameter types; type-specific schema constraints (string pattern and length, numeric range, array item counts, map closed-struct); string and arithmetic expression methods that produce Value results for use in .Set(); and runtime condition methods that produce Condition results for use in .SetIf(), .If(), and placement predicates.

Common chain methods​

These methods are available on every parameter type via baseParam. They control the generated CUE field presence marker, default value, and documentation annotations.

MethodCUE generatedDescription
.Required() *Tname!: typeUser must explicitly provide this field. Cannot be satisfied by defaults or merging.
.Optional() *Tname?: typeField may be absent from input entirely. Identical to bare param for readability.
.Default(value) *Tname: *value | typeSets a default. The parameter becomes non-optional at the CUE level (no ? or !) unless combined with .Optional() / .Required().
.Description(desc string) *T// +usage=descHuman-readable description shown in vela show and generated OpenAPI.
.Short(s string) *T// +short=sSingle-letter CLI shorthand flag (e.g. "i" → -i). Available on String, Int, Bool, Float, Enum.
.Ignore() *T// +ignoreExcludes the field from vela show and OpenAPI output. Available on String, Int, Bool, Float, Enum.
tip

A bare param with no modifier emits name?: type — the same as .Optional(). Use .Optional() explicitly to signal intent in code that will be read by others.

String constraints​

Available on *StringParam (i.e. defkit.String(...)). These constraints appear inside the parameter: block and are enforced by CUE at apply time.

MethodCUE generatedDescription
.Values(values ...string) *StringParam"v1" | "v2" | ...Restricts the string to a fixed set of allowed values, producing a CUE string disjunction.
.OpenEnum() *StringParam"v1" | "v2" | stringLike .Values() but keeps the enum open — any string is also accepted. Useful for well-known values plus user-defined ones.
.Pattern(regex string) *StringParamstring & =~"regex"Requires the value to match a regular expression.
.MinLen(n int) *StringParamstrings.MinRunes(n)Minimum UTF-8 rune count. Requires the "strings" CUE import (add .WithImports("strings") to the definition).
.MaxLen(n int) *StringParamstrings.MaxRunes(n)Maximum UTF-8 rune count. Same import requirement.
caution

For negative regex constraints (CUE !~), use a raw .WithSchema() string or a defkit.CUEExpr — these are not expressible through the typed chain-method API alone.

Numeric constraints​

Available on *IntParam and *FloatParam.

MethodCUE generatedDescription
.Min(n) *Tint & >=n or float & >=nInclusive lower bound.
.Max(n) *Tint & <=n or float & <=nInclusive upper bound.

When combined with .Default(v) the disjunction reads *v | int & >=n & <=n.

Array constraints​

Available on *ArrayParam.

MethodCUE generatedDescription
.MinItems(n int) *ArrayParamlist.MinItems(n) & [...]Minimum number of array elements. Requires the "list" CUE import (add .WithImports("list") to the definition).
.MaxItems(n int) *ArrayParamlist.MaxItems(n) & [...]Maximum number of array elements. Same import requirement.
.OfEnum(values ...string) *ArrayParam[...("v1" | "v2" | ...)]Constrains each element to one of the given string values.

Map constraints​

Available on *MapParam (and its alias defkit.Object(...)).

MethodCUE generatedDescription
.Closed() *MapParamclose({...})Wraps the generated struct in CUE's close(), rejecting any extra fields not explicitly declared via .WithFields().

String expressions​

Available on *StringParam. These methods return a Value for use in .Set() / .SetIf() value positions — they do not affect the parameter: schema block.

MethodCUE generatedReturns
.Concat(suffix string) Valueparameter.name + "suffix"Value
.Prepend(prefix string) Value"prefix" + parameter.nameValue
tip

Neither Concat nor Prepend chains further — both return Value, not *StringParam. To concatenate two parameters together, use defkit.Plus(...) from the value-expression API.

Arithmetic expressions​

Available on *IntParam. These return a Value.

MethodCUE generatedReturns
.Add(n int) Valueparameter.name + nValue
.Sub(n int) Valueparameter.name - nValue
.Mul(n int) Valueparameter.name * nValue
.Div(n int) Valueparameter.name / nValue

Arithmetic results are integer expressions. Do not assign them to Kubernetes fields that require a string (e.g. env[].value).

Runtime conditions — presence​

These methods produce Condition values for use in .SetIf(), .If()/.EndIf(), .OutputsIf(), and placement predicates. They are available on all parameter types via baseParam.

MethodCUE generatedDescription
.IsSet() Condition`parameter["name"] != __`
.NotSet() Condition`parameter["name"] == __`
.Eq(val any) Conditionparameter.name == valEquality comparison against a literal.
.Ne(val any) Conditionparameter.name != valInequality comparison.
.Gt(val any) Conditionparameter.name > valGreater-than comparison. Meaningful for numeric params.
.Gte(val any) Conditionparameter.name >= valGreater-than-or-equal.
.Lt(val any) Conditionparameter.name < valLess-than comparison.
.Lte(val any) Conditionparameter.name <= valLess-than-or-equal.

Runtime conditions — boolean, string, and collection predicates​

BoolParam conditions​

MethodCUE generatedDescription
.IsTrue() Conditionif parameter.nameTruthy guard — shorter and more idiomatic than .Eq(true).
.IsFalse() Conditionif !parameter.nameFalsy guard — shorter than .Eq(false).

StringParam conditions​

MethodCUE generatedDescription
.In(values ...string) Conditionparameter.name == "v1" || ...True when the value is one of the listed strings.
.Matches(pattern string) Conditionparameter.name =~ "pattern"True when the value matches a regex.
.Contains(substr string) Conditionstrings.Contains(parameter.name, "sub")True when the string contains a substring. Requires "strings" import.
.StartsWith(prefix string) Conditionstrings.HasPrefix(parameter.name, "pfx")True when the string starts with a prefix. Requires "strings" import.
.EndsWith(suffix string) Conditionstrings.HasSuffix(parameter.name, "sfx")True when the string ends with a suffix. Requires "strings" import.

IntParam and FloatParam conditions​

MethodCUE generatedDescription
.In(values ...T) Conditionparameter.name == v1 || ...True when the value is one of the listed integers or floats.

ArrayParam runtime conditions​

These conditions are distinct from .MinItems()/.MaxItems() (schema constraints). They control template logic only.

MethodCUE generatedDescription
.IsSet() Condition`parameter["x"] != __`
.IsNotEmpty() Conditionlen(parameter.x) > 0True when present and non-empty.
.IsEmpty() Conditiontwo if blocks: absent OR emptyTrue when absent or empty. Renders as two separate blocks because CUE cannot express `
.LenEq(n int) Conditionlen(parameter.x) == nExact length. LenEq(0) is equivalent to IsEmpty().
.LenGt(n int) Conditionlen(parameter.x) > nLength strictly greater than n.
.LenGte(n int) Conditionlen(parameter.x) >= nLength greater than or equal to n.
.LenLt(n int) Conditionlen(parameter.x) < nLength strictly less than n.
.LenLte(n int) Conditionlen(parameter.x) <= nLength less than or equal to n.
.Contains(val any) Conditionlist.Contains(parameter.x, val)True when the array contains the given value. Requires "list" import.

MapParam / StringKeyMap runtime conditions​

MethodCUE generatedDescription
.IsSet() Condition`parameter["x"] != __`
.IsNotEmpty() Conditionlen(parameter.x) > 0True when present and non-empty.
.IsEmpty() Conditiontwo if blocks: absent OR emptySame two-block rendering as ArrayParam.IsEmpty().
.HasKey(key string) Condition`parameter.x.key != __`
.LenEq(n int) Conditionlen(parameter.x) == nExact entry count. LenEq(0) equivalent to IsEmpty().
.LenGt(n int) Conditionlen(parameter.x) > nEntry count greater than n.

Struct field access​

defkit.Struct(name) and defkit.Object(name) / defkit.Map(name) expose a .Field(fieldPath string) method that returns a *ParamFieldRef. This can be used as a Value in .Set() positions or tested with .IsSet() and .Eq() in condition positions.

MethodCUE generatedDescription
structParam.Field("x") *ParamFieldRefparameter.struct.xReference to a nested field.
mapParam.Field("x") *ParamFieldRefparameter.map.xSame as above for Map/Object.
ref.IsSet() Condition`parameter.struct.x != __`
ref.Eq(val any) Conditionparameter.struct.x == valEquality check on the nested field.
ref.Ne(val any) Conditionparameter.struct.x != valInequality check.

Example​

The chain-methods-demo component exercises every table in this document. From Common chain methods: image.Required().Short("i").Description(...) and readOnly.Default(false). From String constraints: appName.Optional().Pattern(...).MinLen(1).MaxLen(48) and env.Values("dev","staging","prod").Default("dev"). From Numeric constraints: replicas.Default(1).Min(1).Max(20). From Array constraints: ports.MinItems(1).MaxItems(10). From String expressions: appName.Concat("-svc") and appName.Prepend("platform-"). From Arithmetic expressions: replicas.Add(10) lands in spec.minReadySeconds. From Runtime conditions: labels.IsSet(), readOnly.IsTrue(), readOnly.IsFalse(), ports.IsSet(), appName.IsSet(), env.In(...), env.StartsWith(...), env.Contains(...), env.EndsWith(...). Building on the my-platform module scaffolded in Quick Start, drop the file below into my-platform/components/.

package components

import "github.com/oam-dev/kubevela/pkg/definition/defkit"

func ChainMethodsDemo() *defkit.ComponentDefinition {
image := defkit.String("image").
Required().
Short("i").
Description("Container image reference (e.g. nginx:1.25)")

appName := defkit.String("appName").
Optional().
Pattern("^[a-z][a-z0-9-]*$").
MinLen(1).
MaxLen(48).
Description("Application name; must match ^[a-z][a-z0-9-]*$")

env := defkit.String("env").
Values("dev", "staging", "prod").
Default("dev").
Description("Deployment environment")

replicas := defkit.Int("replicas").
Default(1).
Min(1).
Max(20).
Description("Number of pod replicas")

logLevel := defkit.Enum("logLevel").
Values("debug", "info", "warn", "error").
Default("info").
Description("Log verbosity level")

labels := defkit.StringKeyMap("labels").
Optional().
Description("Arbitrary metadata labels spread onto the Deployment")

ports := defkit.Array("ports").
WithFields(
defkit.Int("port"),
defkit.String("name").Optional(),
).
MinItems(1).
MaxItems(10).
Optional().
Description("Container ports; at least one required when provided")

readOnly := defkit.Bool("readOnly").
Default(false).
Description("Mount root filesystem read-only")

return defkit.NewComponent("chain-methods-demo").
Description("Exercises chain methods across all parameter types").
Workload("apps/v1", "Deployment").
Params(image, appName, env, replicas, logLevel, labels, ports, readOnly).
Template(chainMethodsDemoTemplate).
WithImports("list", "strings")
}

func chainMethodsDemoTemplate(tpl *defkit.Template) {
vela := defkit.VelaCtx()

image := defkit.String("image")
appName := defkit.String("appName")
env := defkit.String("env")
replicas := defkit.Int("replicas")
labels := defkit.StringKeyMap("labels")
ports := defkit.Array("ports").WithFields(
defkit.Int("port"),
defkit.String("name").Optional(),
)
readOnly := defkit.Bool("readOnly")

containerPorts := defkit.NewArray().ForEachWith(ports, func(item *defkit.ItemBuilder) {
v := item.Var()
item.Set("containerPort", v.Field("port"))
item.IfSet("name", func() { item.Set("name", v.Field("name")) })
})

dep := defkit.NewResource("apps/v1", "Deployment").
Set("metadata.name", vela.Name()).
Set("spec.replicas", replicas).
Set("spec.minReadySeconds", replicas.Add(10)).
Set("spec.selector.matchLabels[app.oam.dev/component]", vela.Name()).
Set("spec.template.metadata.labels[app.oam.dev/component]", vela.Name()).
SetIf(labels.IsSet(), "metadata.labels", labels).
SetIf(appName.IsSet(), "spec.template.metadata.labels[app-name]", appName.Concat("-svc")).
SetIf(appName.IsSet(), "spec.template.metadata.labels[prefixed-name]", appName.Prepend("platform-")).
SetIf(env.In("staging", "prod"), "spec.template.metadata.labels[tier]", defkit.Lit("production")).
SetIf(env.StartsWith("dev"), "spec.template.metadata.labels[env-class]", defkit.Lit("non-prod")).
SetIf(env.Contains("prod"), "spec.template.metadata.labels[is-prod]", defkit.Lit("true")).
SetIf(env.EndsWith("ing"), "spec.template.metadata.labels[is-transient]", defkit.Lit("true")).
Set("spec.template.spec.containers[0].name", vela.Name()).
Set("spec.template.spec.containers[0].image", image).
SetIf(readOnly.IsTrue(), "spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem", defkit.Lit(true)).
SetIf(readOnly.IsFalse(), "spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem", defkit.Lit(false)).
SetIf(ports.IsSet(), "spec.template.spec.containers[0].ports", containerPorts).
Set("spec.template.spec.containers[0].resources.requests.cpu", defkit.Lit("100m")).
Set("spec.template.spec.containers[0].resources.limits.cpu", defkit.Lit("200m"))

tpl.Output(dep)
}

func init() { defkit.Register(ChainMethodsDemo()) }

Reproduce the CUE on the right with:

vela def validate-module ./my-platform
vela def gen-module ./my-platform -o ./generated-cue

Apply and verify​

Apply the definition and the Application YAML above against a live cluster:

vela def apply ./generated-cue/components/chain-methods-demo.cue
vela up -f chain-methods-app.yaml
vela status chain-methods-app --namespace default
About:

Name: chain-methods-app
Namespace: default
Healthy: true
Details: running

Services:

- Name: chain-methods
Cluster: local
Namespace: default
Type: chain-methods-demo
Health: true
No trait applied

Inspect the rendered Deployment to confirm that each chain method produced the expected output. The output below was captured live against a k3d cluster:

$ kubectl get deployment chain-methods -n default \
-o jsonpath='{.spec.template.metadata.labels}' \
| python3 -m json.tool
{
"app-name": "my-service-svc",
"app.oam.dev/component": "chain-methods",
"is-transient": "true",
"prefixed-name": "platform-my-service",
"tier": "production"
}

$ kubectl get deployment chain-methods -n default \
-o jsonpath='replicas={.spec.replicas} minReadySeconds={.spec.minReadySeconds} readOnly={.spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem}'
replicas=3 minReadySeconds=13 readOnly=false

$ kubectl get deployment chain-methods -n default \
-o jsonpath='NAME={.metadata.name} READY={.status.readyReplicas}/{.status.replicas}'
NAME=chain-methods READY=3/3

env.In("staging","prod") fires for env=staging and writes tier=production. appName.Concat("-svc") produces app-name=my-service-svc and appName.Prepend("platform-") produces prefixed-name=platform-my-service. env.EndsWith("ing") fires for staging and writes is-transient=true. replicas=3 with .Add(10) yields minReadySeconds=13. ports.MinItems(1).MaxItems(10) is enforced by the CUE schema at apply time; both ports land as containerPort entries in the rendered Deployment.

Clean up afterwards:

vela delete chain-methods-app --namespace default --yes
kubectl delete componentdefinition chain-methods-demo -n vela-system