Skip to content

slashdevops/qfv

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Query Filters Validator (QFV)

Go Reference GitHub go.mod Go version license Release release

A Go library for parsing and validating the query expressions commonly used in REST APIs and database queries — fields selection, filtering, and sorting. Each parser is driven by an allow-list of fields, so only fields you permit can appear in a query, helping secure your endpoints against invalid or malicious input.

Install

go get github.com/slashdevops/qfv@latest

Update to the latest release with go get -u github.com/slashdevops/qfv@latest.

Quick start

package main

import (
    "fmt"
    "log"

    qfv "github.com/slashdevops/qfv"
)

func main() {
    allowedFields := []string{"first_name", "last_name", "email", "created_at"}

    // Parsers are safe to build once and reuse across goroutines.
    filterParser := qfv.NewFilterParser(allowedFields)
    sortParser := qfv.NewSortParser(allowedFields)
    fieldsParser := qfv.NewFieldsParser(allowedFields)

    node, err := filterParser.Parse("first_name = 'John' AND created_at > '2023-01-01'")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(node.String()) // ((first_name = 'John') AND (created_at > '2023-01-01'))

    if _, err := sortParser.Parse("first_name ASC, created_at DESC"); err != nil {
        log.Fatal(err)
    }
    if _, err := fieldsParser.Parse("first_name, last_name, email"); err != nil {
        log.Fatal(err)
    }
}

Features

  • Three validators — fields selection, filtering, and sorting, each gated by an allow-list of fields (nested dot-notation like user.profile.age supported).
  • Rich, PostgreSQL-flavored filter grammar — comparison, logical, IN, BETWEEN [SYMMETRIC], LIKE/ILIKE, SIMILAR TO, POSIX regex, IS NULL, IS [NOT] TRUE/FALSE/UNKNOWN, and IS [NOT] DISTINCT FROM.
  • Configurable — restrict which operators or sort directions are allowed.
  • Returns an AST you can walk or render, with precise, aggregated errors.
  • Concurrency-safe parsers.

How it works

Every parser is gated by the same allow-list of fields. Untrusted query-string parameters go in; validated, structured values come out — an AST for filters, typed lists for fields and sorting — so nothing outside your allow-list ever reaches your data layer.

flowchart LR
    Q["HTTP query string<br/>?fields=…&filter=…&sort=…"]

    Q --> FP["FieldsParser"]
    Q --> FI["FilterParser"]
    Q --> SP["SortParser"]

    AL(["Allow-list of fields"]) -. gates .-> FP
    AL -. gates .-> FI
    AL -. gates .-> SP

    FP --> FN["FieldsNode<br/>[]string"]
    FI --> AST["Filter AST<br/>(Node tree)"]
    SP --> SN["SortNode<br/>[]SortFieldNode"]

    FN --> APP["Your handler / SQL builder"]
    AST --> APP
    SN --> APP

    APP --> DB[("Database")]
Loading

The filter parser is a hand-written recursive-descent parser: a Lexer tokenizes the input, then the parser builds the AST while honoring operator precedence (OR < AND < comparison) and the allow-list.

flowchart LR
    IN["input string"] --> LEX["Lexer<br/>tokenize"]
    LEX --> TOK["[]Token"]
    TOK --> PAR["FilterParser<br/>recursive descent"]
    PAR --> AST["AST root (Node)"]
    PAR -. "collects every error" .-> ERR["errors.Join(…)"]
Loading

Documentation

Full documentation lives in docs/:

API reference and runnable examples are on pkg.go.dev.

License

See the repository for license details.

About

Abstract Syntax Tree (AST) parser for query fields, filters and sort operations

Resources

License

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Sponsor this project

Packages

 
 
 

Contributors

Languages