Write Your First Filter

This tutorial takes a query written by a person and evaluates it against service records. The application owns the schema and runtime; the query only chooses which records match.

1. Describe the record

The example service tracks support tickets. Its filterable fields are a team name and an active flag:

schema.Struct(
    schema.String("team"),
    schema.Bool("active"),
)

An explicit schema lets HFF reject misspelled fields and incompatible operations before the service evaluates any records.

2. Compile a human-authored query

The filter might come from a search box or saved view:

team="support" active=true

Spaces between predicates mean AND. Configure the engine with the schema and the capabilities your service intends to expose, then compile the source:

e, err := engine.New(
    engine.WithSchema(schema.Struct(
        schema.String("team"),
        schema.Bool("active"),
    )),
    engine.WithCapabilities(capabilities.Standard()),
)
if err != nil {
    return err
}

program, err := e.Compile(ctx, `team="support" active=true`)
if err != nil {
    return err
}

Compilation checks syntax, field names, types, capabilities, and query limits. It does not evaluate a record. See Compile a query for structured diagnostics and the distinction between compilation and backend building.

3. Build and match locally

Build a reusable local filter from the typed program. Then pass records as immutable HFF values:

filter, err := local.Build(ctx, program)
if err != nil {
    return err
}

record := hff.Object(map[string]hff.Value{
    "team":   hff.String("support"),
    "active": hff.Bool(true),
})
matched, err := filter.Match(ctx, record)
if err != nil {
    return err
}
fmt.Println(matched) // true

Match validates the record against the program's input schema and evaluates the filter. A completed non-match is false, nil; invalid input, cancellation, or an exhausted runtime budget is an error.

Run the complete example

From the repository root:

go run ./examples/tutorial-first-filter

It prints:

ticket-17: true
ticket-18: false

Continue with Use a filter in a service to move compilation out of the request path and reuse validated records.

Explore HFF
Search documentation

Search the language specification and guides.