Documentation ¶
Overview ¶
Package bloblang provides high level APIs for registering custom Bloblang plugins, as well as for parsing and executing Bloblang mappings.
Plugins can either be registered globally, and will be accessible to any component parsing Bloblang expressions in the executable, or they can be registered as part of an isolated environment.
Example (BloblangPlugins) ¶
ExampleBloblangPlugins demonstrates how to create Bloblang methods and functions and execute them with a Bloblang mapping.
package main import ( "encoding/json" "fmt" "math/rand" "github.com/Jeffail/benthos/v3/public/bloblang" ) func main() { if err := bloblang.RegisterMethod("cuddle", func(args ...interface{}) (bloblang.Method, error) { var prefix string var suffix string if err := bloblang.NewArgSpec(). StringVar(&prefix). StringVar(&suffix). Extract(args); err != nil { return nil, err } return bloblang.StringMethod(func(s string) (interface{}, error) { return prefix + s + suffix, nil }), nil }); err != nil { panic(err) } if err := bloblang.RegisterMethod("shuffle", func(_ ...interface{}) (bloblang.Method, error) { rand := rand.New(rand.NewSource(0)) return bloblang.ArrayMethod(func(in []interface{}) (interface{}, error) { out := make([]interface{}, len(in)) copy(out, in) rand.Shuffle(len(out), func(i, j int) { out[i], out[j] = out[j], out[i] }) return out, nil }), nil }); err != nil { panic(err) } if err := bloblang.RegisterFunction("add_but_always_slightly_wrong", func(args ...interface{}) (bloblang.Function, error) { var left, right float64 if err := bloblang.NewArgSpec(). Float64Var(&left). Float64Var(&right). Extract(args); err != nil { return nil, err } return func() (interface{}, error) { return left + right + 0.02, nil }, nil }); err != nil { panic(err) } mapping := ` root.new_summary = this.summary.cuddle("meow", "woof") root.shuffled = this.names.shuffle() root.num = add_but_always_slightly_wrong(1.2, 2.6) ` exe, err := bloblang.Parse(mapping) if err != nil { panic(err) } res, err := exe.Query(map[string]interface{}{ "summary": "quack", "names": []interface{}{"denny", "pixie", "olaf", "jen", "spuz"}, }) if err != nil { panic(err) } jsonBytes, err := json.Marshal(res) if err != nil { panic(err) } fmt.Println(string(jsonBytes)) }
Output: {"new_summary":"meowquackwoof","num":3.82,"shuffled":["olaf","jen","pixie","denny","spuz"]}
Example (BloblangRestrictedEnvironment) ¶
ExampleBloblangRestrictedEnvironment demonstrates how to create and use an isolated Bloblang environment with some standard functions removed.
package main import ( "encoding/json" "fmt" "strings" "github.com/Jeffail/benthos/v3/public/bloblang" ) func main() { env := bloblang.NewEnvironment().WithoutFunctions("env", "file") if err := env.RegisterMethod("custom_thing", func(args ...interface{}) (bloblang.Method, error) { return bloblang.StringMethod(func(s string) (interface{}, error) { return strings.ToUpper(s), nil }), nil }); err != nil { panic(err) } mapping := ` root.foo = this.foo.string() root.bar = this.bar + this.baz root.buz = this.buz.content.custom_thing() ` exe, err := env.Parse(mapping) if err != nil { panic(err) } res, err := exe.Query(map[string]interface{}{ "foo": 50.0, "bar": "first bit ", "baz": "second bit", "buz": map[string]interface{}{ "id": "XXXX", "content": "some nested content", }, }) if err != nil { panic(err) } jsonBytes, err := json.Marshal(res) if err != nil { panic(err) } fmt.Println(string(jsonBytes)) }
Output: {"bar":"first bit second bit","buz":"SOME NESTED CONTENT","foo":"50"}
Index ¶
- Variables
- func RegisterFunction(name string, ctor FunctionConstructor) error
- func RegisterMethod(name string, ctor MethodConstructor) error
- type ArgSpec
- func (a *ArgSpec) AnyVar(i *interface{}) *ArgSpec
- func (a *ArgSpec) BoolVar(b *bool) *ArgSpec
- func (a *ArgSpec) Extract(args []interface{}) error
- func (a *ArgSpec) Float64Var(f *float64) *ArgSpec
- func (a *ArgSpec) Int64Var(i *int64) *ArgSpec
- func (a *ArgSpec) IntVar(i *int) *ArgSpec
- func (a *ArgSpec) StringVar(s *string) *ArgSpec
- type Environment
- func (e *Environment) Parse(blobl string) (*Executor, error)
- func (e *Environment) RegisterFunction(name string, ctor FunctionConstructor) error
- func (e *Environment) RegisterMethod(name string, ctor MethodConstructor) error
- func (e *Environment) WithoutFunctions(names ...string) *Environment
- func (e *Environment) WithoutMethods(names ...string) *Environment
- type Executor
- type Function
- type FunctionConstructor
- type Method
- func ArrayMethod(methodFn func([]interface{}) (interface{}, error)) Method
- func BoolMethod(methodFn func(bool) (interface{}, error)) Method
- func BytesMethod(methodFn func([]byte) (interface{}, error)) Method
- func Float64Method(methodFn func(float64) (interface{}, error)) Method
- func Int64Method(methodFn func(int64) (interface{}, error)) Method
- func ObjectMethod(methodFn func(obj map[string]interface{}) (interface{}, error)) Method
- func StringMethod(methodFn func(string) (interface{}, error)) Method
- func TimestampMethod(methodFn func(time.Time) (interface{}, error)) Method
- type MethodConstructor
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrRootDeleted = errors.New("root was deleted")
ErrRootDeleted is returned by a Bloblang query when the mapping results in the root being deleted. It might be considered correct to do this in situations where filtering is allowed or expected.
Functions ¶
func RegisterFunction ¶
func RegisterFunction(name string, ctor FunctionConstructor) error
RegisterFunction adds a new Bloblang function to the global enviromment. All function names must match the regular expression /^[a-z0-9]+(_[a-z0-9]+)*$/ (snake case).
func RegisterMethod ¶
func RegisterMethod(name string, ctor MethodConstructor) error
RegisterMethod adds a new Bloblang method to the global enviromment. All method names must match the regular expression /^[a-z0-9]+(_[a-z0-9]+)*$/ (snake case).
Types ¶
type ArgSpec ¶
type ArgSpec struct {
// contains filtered or unexported fields
}
ArgSpec provides an API for validating and extracting function or method arguments by registering them with pointer receivers.
func (*ArgSpec) AnyVar ¶
AnyVar creates an argument to follow the previously created argument that can have any value.
func (*ArgSpec) BoolVar ¶
BoolVar creates a boolean argument to follow the previously created argument.
func (*ArgSpec) Extract ¶
Extract the specified typed arguments from a slice of generic arguments. Returns an error if the type of an argument is mismatched, or if the number of arguments is mismatched.
func (*ArgSpec) Float64Var ¶
Float64Var creates a Float64 argument to follow the previously created argument.
func (*ArgSpec) Int64Var ¶
Int64Var creates an int64 argument to follow the previously created argument.
type Environment ¶
type Environment struct {
// contains filtered or unexported fields
}
Environment provides an isolated Bloblang environment where the available features, functions and methods can be modified.
func NewEnvironment ¶
func NewEnvironment() *Environment
NewEnvironment creates a fresh Bloblang environment, starting with the full range of globally defined features (functions and methods), and provides APIs for expanding or contracting the features available to this environment.
It's worth using an environment when you need to restrict the access or capabilities that certain bloblang mappings have versus others.
For example, an environment could be created that removes any functions for accessing environment variables or reading data from the host disk, which could be used in certain situations without removing those functions globally for all mappings.
func (*Environment) Parse ¶
func (e *Environment) Parse(blobl string) (*Executor, error)
Parse a Bloblang mapping using the Environment to determine the features (functions and methods) available to the mapping.
func (*Environment) RegisterFunction ¶
func (e *Environment) RegisterFunction(name string, ctor FunctionConstructor) error
RegisterFunction adds a new Bloblang function to the environment. All function names must match the regular expression /^[a-z0-9]+(_[a-z0-9]+)*$/ (snake case).
func (*Environment) RegisterMethod ¶
func (e *Environment) RegisterMethod(name string, ctor MethodConstructor) error
RegisterMethod adds a new Bloblang method to the environment. All method names must match the regular expression /^[a-z0-9]+(_[a-z0-9]+)*$/ (snake case).
func (*Environment) WithoutFunctions ¶
func (e *Environment) WithoutFunctions(names ...string) *Environment
WithoutFunctions returns a copy of the environment but with a variadic list of function names removed. Instantiation of these removed functions within a mapping will cause errors at parse time.
func (*Environment) WithoutMethods ¶
func (e *Environment) WithoutMethods(names ...string) *Environment
WithoutMethods returns a copy of the environment but with a variadic list of method names removed. Instantiation of these removed methods within a mapping will cause errors at parse time.
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor stores a parsed Bloblang mapping and provides APIs for executing it.
func Parse ¶
Parse a Bloblang mapping allowing the use of the globally accessible range of features (functions and methods).
func (*Executor) Overlay ¶ added in v3.46.0
Overlay executes a Bloblang mapping against a value, where assignments are overlayed onto an existing structure.
func (*Executor) Query ¶
Query executes a Bloblang mapping against a value and returns the result. The argument and return values can be structured using the same map[string]interface{} and []interface{} types as would be returned by the Go standard json package unmarshaler.
If the mapping results in the root of the new document being deleted then ErrRootDeleted is returned, which can be used as a signal to filter rather than fail the mapping.
type Function ¶
type Function func() (interface{}, error)
Function defines a Bloblang function, arguments are provided to the constructor, allowing the implementation of this function to resolve them statically when possible.
type FunctionConstructor ¶
FunctionConstructor defines a constructor for a Bloblang function, where a variadic list of arguments are provided.
When a function is parsed from a mapping with static arguments the constructor will be called only once at parse time. When a function is parsed with dynamic arguments, such as a value derived from the mapping input, the constructor will be called on each invocation of the mapping with the derived arguments.
For a convenient way to perform type checking and coercion on the arguments use an ArgSpec.
type Method ¶
type Method func(v interface{}) (interface{}, error)
Method defines a Bloblang function that executes on a value. Arguments are provided to the constructor, allowing the implementation of this method to resolve them statically when possible.
In order to avoid type checking the value use one of the typed variants such as StringMethod.
func ArrayMethod ¶
ArrayMethod creates a general method signature from an array method by performing type checking on the method target.
func BoolMethod ¶
BoolMethod creates a general method signature from a bool method by performing type checking on the method target.
func BytesMethod ¶
BytesMethod creates a general method signature from a byte slice method by performing type checking on the method target.
func Float64Method ¶
Float64Method creates a general method signature from a float method by performing type checking on the method target.
func Int64Method ¶
Int64Method creates a general method signature from an int method by performing type checking on the method target.
func ObjectMethod ¶
ObjectMethod creates a general method signature from an object method by performing type checking on the method target.
func StringMethod ¶
StringMethod creates a general method signature from a string method by performing type checking on the method target.
type MethodConstructor ¶
MethodConstructor defines a constructor for a Bloblang method, where a variadic list of arguments are provided.
When a method is parsed from a mapping with static arguments the constructor will be called only once at parse time. When a method is parsed with dynamic arguments, such as a value derived from the mapping input, the constructor will be called on each invocation of the mapping with the derived arguments.
For a convenient way to perform type checking and coercion on the arguments use an ArgSpec.