Skip to main content
Version: v1.11-alpha

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