Skip to main content
Version: v1.11-alpha

Register & Output

defkit.Register(def) auto-registers a definition when its package is imported. Call it in init() so the registration happens automatically when the package is blank-imported. The output methods generate different representations of the definition. The Complete Example at the end of the page shows a real, cluster-verified component together with each output method's actual rendered output.

defkit.Register and init()

The registration pattern relies on Go's init() function, which runs automatically when a package is imported. By calling defkit.Register() inside init(), each definition self-registers without any explicit wiring:

Go — defkit
func Webservice() *defkit.ComponentDefinition {
// ...
return defkit.NewComponent("webservice").
Workload("apps/v1", "Deployment").
Params(image, replicas).
Template(webserviceTemplate)
}

// Auto-register when package is imported
func init() { defkit.Register(Webservice()) }

The cmd/register/main.go entry point uses blank imports to trigger all init() calls across every package, then writes the serialized registry to stdout:

cmd/register/main.go
package main

import (
"fmt"
"os"

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

// Blank imports trigger init() in each package,
// registering all definitions automatically.
_ "my-platform/components"
_ "my-platform/policies"
_ "my-platform/traits"
_ "my-platform/workflowsteps"
)

func main() {
output, err := defkit.ToJSON()
if err != nil {
fmt.Fprintf(os.Stderr, "failed to serialize registry: %v\n", err)
os.Exit(1)
}
fmt.Print(string(output))
}

defkit.ToJSON() ([]byte, error) serializes every registered definition into a JSON payload that vela def apply-module reads to apply definitions to the cluster. Always check the error — there is no panic path; a malformed definition surfaces as a non-nil error here.

Output Methods

ComponentDefinition exposes four output methods; TraitDefinition, PolicyDefinition, and WorkflowStepDefinition expose only the two universal ones (ToCue and ToYAML).

MethodReturnApplies toDescription
.ToCue() stringstringAll four kindsGenerate the CUE definition as a string.
.ToCueWithImports(imports ...string) stringstringComponentDefinition onlyGenerate CUE with explicit import declarations prepended. Use defkit.CUEImports.Strings, defkit.CUEImports.Strconv, etc. for the standard CUE imports.
.ToParameterSchema() stringstringComponentDefinition onlyGenerate only the parameter: { ... } CUE block (without the full definition wrapper).
.ToYAML() ([]byte, error)[]byte, errorAll four kindsGenerate the Kubernetes YAML manifest for the X-Definition CRD; the CUE template is embedded in spec.schematic.cue.template.
tip

ToCue() and ToYAML() are useful in unit tests to assert on the generated output without a live cluster. Use them with go test to verify that parameter defaults, types, and structure match expectations.

Complete Example

The register-output-demo component below is a minimal ComponentDefinition (Deployment workload, two parameters) that self-registers via init() and exercises all four output methods. Drop the file into the components/ directory of a defkit module scaffolded via Quick Start, then vela def apply-module ./my-platform to register the definition with the cluster. The output panes show the actual bytes that comp.ToCue(), comp.ToCueWithImports(...), comp.ToParameterSchema(), and comp.ToYAML() return for this component — generated by running go run ./cmd/dump (or any small driver that calls these methods) against the module and pasted verbatim.

// my-platform/components/register_output_demo.go
package components

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

func RegisterOutputDemo() *defkit.ComponentDefinition {
image := defkit.String("image").Description("Container image")
replicas := defkit.Int("replicas").Default(1).Description("Replica count")

return defkit.NewComponent("register-output-demo").
Description("Minimal component demonstrating defkit.Register and the four output methods").
Workload("apps/v1", "Deployment").
Params(image, replicas).
Template(registerOutputDemoTemplate)
}

func registerOutputDemoTemplate(tpl *defkit.Template) {
vela := defkit.VelaCtx()
image := defkit.String("image")
replicas := defkit.Int("replicas")

dep := defkit.NewResource("apps/v1", "Deployment").
Set("metadata.name", vela.Name()).
Set("spec.replicas", replicas).
Set("spec.selector.matchLabels[app.oam.dev/component]", vela.Name()).
Set("spec.template.metadata.labels[app.oam.dev/component]", vela.Name()).
Set("spec.template.spec.containers[0].name", vela.Name()).
Set("spec.template.spec.containers[0].image", image)
tpl.Output(dep)
}

// Auto-register when this package is blank-imported by cmd/register.
func init() { defkit.Register(RegisterOutputDemo()) }
// cmd/register-output-demo/main.go — exercises every output method on the component.
package main

import (
"fmt"
"os"

"github.com/oam-dev/kubevela/pkg/definition/defkit"
"my-platform/components"
)

func main() {
comp := components.RegisterOutputDemo()

fmt.Println(comp.ToCue())

fmt.Println(comp.ToCueWithImports(
defkit.CUEImports.Strings,
defkit.CUEImports.Strconv,
))

fmt.Println(comp.ToParameterSchema())

yamlBytes, err := comp.ToYAML()
if err != nil {
fmt.Fprintf(os.Stderr, "ToYAML: %v\n", err)
os.Exit(1)
}
fmt.Print(string(yamlBytes))
}

Apply the registered definition with the conventional pipeline:

vela def apply-module ./my-platform        # discovers every Register() via the cmd/register entry point
vela up -f probe-application.yaml # deploys an Application that references the component