This directory contains executable Go examples showcasing the CEL-Go APIs and language features. All examples correspond to topics on CEL by Example and are implemented as Go Example...() functions runnable via go test and viewable via godoc.
Compile and evaluate expressions using cel.Compile():
package main
import (
"fmt"
"log"
"github.com/google/cel-go/cel"
)
func main() {
prg, err := cel.Compile(`"Hello world! I'm " + name + "."`,
cel.Variable("name", cel.StringType),
)
if err != nil {
log.Fatalln(err)
}
out, _, err := prg.Eval(map[string]any{
"name": "CEL",
})
if err != nil {
log.Fatalln(err)
}
fmt.Println(out)
// Output: Hello world! I'm CEL.
}For custom options and extensions:
prg, err := cel.Compile(`"%s! I'm %s.".format([greeting, name])`,
ext.Strings(),
cel.Variable("greeting", cel.StringType),
cel.Variable("name", cel.StringType),
)
out, _, err := prg.Eval(map[string]any{
"greeting": "Hello world",
"name": "CEL",
})Source code: example_cel_compile_test.go | Source code: example_cel_context_eval_test.go
Covers string functions (endsWith, contains, startsWith, matches, size), string concatenation (+), numeric comparisons, and ext.Strings() extensions:
prg, _ := cel.Compile(`"hello world".replace("world", "CEL")`, ext.Strings())
out, _, _ := prg.Eval(cel.NoVars())
fmt.Println(out) // hello CELSource code: example_cel_strings_and_numbers_test.go
Membership (in), size (size()), indexing ([0]), quantifier macros (exists(), all()), and filtering (filter()):
prg, _ := cel.Compile(`tags.exists(t, t.startsWith("ex"))`, cel.Variable("tags", cel.DynType))
out, _, _ := prg.Eval(map[string]any{
"tags": []string{"express", "gift-wrapped"},
})
fmt.Println(out) // trueSource code: example_cel_collections_test.go
Time component extraction (getFullYear(), getHours()), timezones, timestamp arithmetic, and epoch conversions:
prg, _ := cel.Compile(`timestamp("2024-01-15T10:30:45Z") + duration("1h")`)
out, _, _ := prg.Eval(cel.NoVars())
fmt.Println(out) // 2024-01-15 11:30:45 +0000 UTCSource code: example_cel_time_test.go
Logical operators (!, &&, ||), short-circuiting, and conditional (ternary) operators:
prg, _ := cel.Compile(`age >= 18 ? "adult" : "minor"`, cel.Variable("age", cel.IntType))
out, _, _ := prg.Eval(map[string]any{"age": 20})
fmt.Println(out) // adultSource code: example_cel_logic_and_conditions_test.go
Building maps, list transformation with map(), and filtering before transformation:
prg, _ := cel.Compile(`nums.map(x, x % 2 == 0, x * 10)`, cel.Variable("nums", cel.ListType(cel.IntType)))
out, _, _ := prg.Eval(map[string]any{
"nums": []int64{1, 2, 3, 4, 5},
})
fmt.Println(out) // [20, 40]Source code: example_cel_transforming_data_test.go
Type casting (int(), uint(), double(), string(), bytes(), dyn()) and type inspection (type(x)):
prg, _ := cel.Compile(`type(42) == int`)
out, _, _ := prg.Eval(cel.NoVars())
fmt.Println(out) // trueSource code: example_cel_type_conversions_test.go
Protobuf message construction, enums, field presence has(), default values, wrappers (StringValue, BoolValue), and google.protobuf.Struct:
prg, _ := cel.Compile(`has(user.single_string)`,
cel.Types(&proto3pb.TestAllTypes{}),
cel.Variable("user", cel.ObjectType("google.expr.proto3.test.TestAllTypes")),
)
out, _, _ := prg.Eval(map[string]any{
"user": &proto3pb.TestAllTypes{SingleString: "Alice"},
})
fmt.Println(out) // trueSource code: example_cel_protocol_buffers_test.go
Arithmetic, ordering, equality, and null handling:
prg, _ := cel.Compile(`(2 + 3) * 4`)
out, _, _ := prg.Eval(cel.NoVars())
fmt.Println(out) // 20Source code: example_cel_operators_test.go
Extend CEL with global functions (cel.Overload) or member functions (cel.MemberOverload):
prg, _ := cel.Compile(`shake_hands(i, you)`,
cel.Variable("i", cel.StringType),
cel.Variable("you", cel.StringType),
cel.Function("shake_hands",
cel.Overload("shake_hands_string_string",
[]*cel.Type{cel.StringType, cel.StringType},
cel.StringType,
cel.BinaryBinding(func(lhs, rhs ref.Val) ref.Val {
return types.String(fmt.Sprintf("%s and %s are shaking hands.", lhs, rhs))
}),
),
),
)
out, _, _ := prg.Eval(map[string]any{"i": "CEL", "you": "world"})
fmt.Println(out) // CEL and world are shaking hands.Source code: example_cel_custom_functions_test.go
Define AST transformation macros using parser.NewGlobalMacro or parser.NewReceiverMacro:
joinMacro := parser.NewGlobalMacro("join_str", 2, func(eh parser.ExprHelper, target ast.Expr, args []ast.Expr) (ast.Expr, *common.Error) {
space := eh.NewLiteral(types.String(" "))
first := eh.NewCall(operators.Add, args[0], space)
return eh.NewCall(operators.Add, first, args[1]), nil
})
prg, _ := cel.Compile(`join_str("Hello", "World")`, cel.Macros(joinMacro))
out, _, _ := prg.Eval(cel.NoVars())
fmt.Println(out) // Hello WorldSource code: example_cel_custom_macros_test.go
Static cost estimation with env.EstimateCost() and dynamic limit enforcement with cel.CostTracking() & cel.CostLimit():
env, _ := cel.NewEnv(cel.Variable("items", cel.ListType(cel.IntType)))
ast, _ := env.Compile(`items.map(x, x * x).size()`)
cost, _ := env.EstimateCost(ast, costEstimator{hints: map[string]uint64{"items": 5, "items.@items": 10}})
prg, _ := env.Program(ast, cel.CostTracking(runtimeEstimator{}), cel.CostLimit(1000))
out, details, _ := prg.Eval(map[string]any{"items": []int64{1, 2, 3}})
fmt.Println(out, *details.ActualCost())Source code: example_cel_execution_cost_test.go
Handling runtime errors and variable shadowing rules in macros:
Source code: example_cel_advanced_test.go
Export Go structs into CEL and map struct field names using json, yaml, or cel struct tags:
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Roles []string `json:"roles"`
}
prg, _ := cel.Compile(`user.name == "Alice" && user.age >= 18`,
cel.Variable("user", cel.ObjectType("examples.User")),
ext.NativeTypes(reflect.TypeOf(User{}), ext.ParseStructTag("json")),
)
out, _, _ := prg.Eval(map[string]any{"user": User{Name: "Alice", Age: 30, Roles: []string{"admin"}}})
fmt.Println(out) // trueSource code: example_cel_native_structs_test.go
Run all examples locally with go test:
go test -v ./examples/...For interactive online examples, visit CEL by Example.