hush

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2026 License: MIT Imports: 10 Imported by: 0

README

hush

Go Reference Go Report Card GitHub release

A Go library for parsing and validating structured query strings from URL parameters.

hush turns URL query strings like filters[title][$containsi]=go&sort[0]=createdAt:desc&fields[0]=title into a typed, validated Query object you can use to drive database queries, API filters, or search logic.

Why?

Building an API means dealing with query parameters like filters, sorting, field selection, pagination. Doing it ad-hoc leads to:

  • Repetitive boilerplate every endpoint reimplements the same parsing and validation
  • Inconsistent errors each endpoint reports validation failures differently
  • Security gaps missing validation leaves your API open to malicious queries
  • Maintenance burden schema changes require hunting down scattered parsing code

Install

go get github.com/DhimasYulian/hush

Quick Start

package main

import (
    "fmt"
    "net/url"

    "github.com/DhimasYulian/hush"
)

func main() {
    // 1. Define a schema (what fields/operators are allowed)
    schema, err := hush.NewSchema("article").
        Filterable("title", hush.TypeString, hush.OpEq, hush.OpContainsi).
        Filterable("views", hush.TypeNumber, hush.OpGt, hush.OpLt).
        Sortable("title", "createdAt").
        Selectable("title", "body", "createdAt").
        MaxLimit(100).
        Build()
    if err != nil {
        panic(err)
    }

    // 2. Parse query string values into a validated Query
    values := url.Values{
        "filters[title][$containsi]": {"go"},
        "sort[0]":                    {"createdAt:desc"},
        "fields[0]":                  {"title"},
        "pagination[limit]":          {"25"},
    }

    query, err := hush.Parse(values, schema)
    if err != nil {
        fmt.Println("validation error:", err)
        return
    }

    fmt.Printf("%+v\n", query)
}

How It Works

hush processes query strings through a three-stage pipeline:

url.Values  -->  Parse  -->  Build  -->  Validate  -->  *Query
  1. Parse -- Splits URL parameter keys into structured path segments using LHS (left-hand side) bracket notation — the path structure is encoded in the key itself, not the value. filters[title][$containsi] becomes ["filters", "title", "$containsi"].

  2. Build -- Assembles parsed segments into a typed query tree. Produces Query with Filters, Fields, Sort, Pagination, and Populates.

  3. Validate -- Checks the query against a Schema to ensure only declared fields, operators, and paths are used. Returns structured errors with context.

Main Types

Type Description
Schema Defines which fields are filterable, sortable, selectable, groupable, and aggregatable, and which relations are available. Built via SchemaBuilder.
Query The parsed and validated result. Contains Filters, Fields, Sort, GroupBy, Aggregations, Pagination, and Populates.
Filter Interface for filter nodes: Condition, And, Or, Not.
Condition A leaf filter: a field path + operator + value(s).
Sort A field path and direction for ordering.
Aggregation A computed aggregate function (count, sum, avg) with an alias and optional field.
Pagination Optional Start, Limit, and WithCount values.
Populate A relation to include, optionally with its own fields, sorts, filters, and nested populates.
Error Structured validation error with Kind, Path, Field, Operator, and Message.

Supported Operators

Operator Constant Description
$eq OpEq Equal
$ne OpNe Not equal
$gt OpGt Greater than
$gte OpGte Greater than or equal
$lt OpLt Less than
$lte OpLte Less than or equal
$in OpIn In list
$notIn OpNotIn Not in list
$between OpBetween Between two values
$contains OpContains String contains
$containsi OpContainsi String contains (case-insensitive)
$startsWith OpStartsWith String starts with
$endsWith OpEndsWith String ends with
$null OpNull Is null
$notNull OpNotNull Is not null

Query String Syntax

Filters
filters[field][$operator]=value
filters[relation][field][$operator]=value
filters[$and][0][field][$operator]=value
filters[$or][0][field][$operator]=value
filters[$not][field][$operator]=value
Fields (select specific columns)
fields[0]=title
fields[1]=body
Sort
sort[0]=createdAt:desc
sort[1]=title:asc

Direction defaults to asc if omitted.

Group By
groupBy[0]=status
groupBy[1]=category

Shorthand (single value): groupBy=status

Fields must be declared Groupable in the schema.

Aggregations
aggregations[total][func]=count
aggregations[totalSalary][func]=sum
aggregations[totalSalary][field]=salary
aggregations[avgAge][func]=avg
aggregations[avgAge][field]=age

Supported functions: count, sum, avg. The field parameter is optional for count (defaults to *), required for sum and avg. Fields must be declared Aggregatable in the schema.

Pagination
pagination[start]=0
pagination[limit]=25
pagination[withCount]=true
Populate (include relations)
populate[0]=author
populate[author][fields][0]=name
populate[author][sort][0]=name:asc
populate[author][filters][name][$eq]=Alice
populate[author][populate][0]=profile

Wildcard (select all relations):

populate=*

Error Handling

hush returns structured errors that you can inspect with errors.Is and errors.As:

query, err := hush.Parse(values, schema)
if err != nil {
    var qerr *hush.Error
    if errors.As(err, &qerr) {
        fmt.Println("kind:", qerr.Kind)       // e.g. ErrOperatorNotAllowed
        fmt.Println("field:", qerr.Field)      // e.g. "title"
        fmt.Println("operator:", qerr.Operator) // e.g. "$containsi"
        fmt.Println("message:", qerr.Message)
    }
}

Parse and build errors fail on the first error. Validation errors accumulate across all sections (filters, fields, sort, populate, pagination) and are joined via errors.Join.

GORM adapter

hush/gorm is a first-class adapter: a validated query translates to GORM clauses with no per-operator code, tested against SQLite and Postgres.

import hushgorm "github.com/DhimasYulian/hush/gorm"

q, err := hush.Parse(values, schema)
if err != nil { /* ... */ }

// db.Scopes(gorm.Scopes(schema, q)) is a GORM scope.
rows := db.Model(&Article{}).Scopes(hushgorm.Scopes(schema, q)).Find(&articles)

The scope handles SELECT (whitelisted fields, groupBy, aggregate aliases), WHERE (every hush operator, typed values, LIKE escaping, logical grouping), ORDER BY, GROUP BY, LIMIT/OFFSET, and nested PRELOAD with per-relation whitelists and max-depth enforcement.

A complete end-to-end walkthrough — schema, parse, scope, result mapping, and eager loading — is available as the runnable gorm.Scopes example.

Querying with the scope
// Values parsed from a request:
values := url.Values{
	"filters[title][$containsi]":           {"go"},
	"filters[views][$gte]":                 {"50"},
	"filters[status][$eq]":                 {"published"},
	"sort[0]":                              {"createdAt:desc"},
	"fields[0]":                            {"title"},
	"pagination[limit]":                    {"25"},
	"pagination[start]":                    {"0"},
	"populate[author][fields][0]":          {"name"},
	"populate[author][filters][name][$eq]": {"Alice"},
}

q, err := hush.Parse(values, schema)
if err != nil { /* ... */ }

if err := db.Model(&Article{}).
	Scopes(hushgorm.Scopes(schema, q)).
	Find(&articles).Error; err != nil { /* ... */ }
  • Pagination & has-more: pagination[withCount] defaults to true. With a limit set, the scope fetches limit+1 rows so you can detect another page:

    hasMore := len(articles) > limit
    

    Set pagination[withCount]=false for an exact limit.

  • Group by & aggregations: groupBy columns and aggregations aliases are SELECTed, so scan into a struct whose fields match the aliases:

    var summaries []struct {
      Status     string
      Cnt        int
      TotalViews float64
    }
    db.Model(&Article{}).Scopes(hushgorm.Scopes(schema, q)).Find(&summaries)
    

    for groupBy[0]=status, aggregations[cnt][func]=count, aggregations[total_views][func]=sum, aggregations[total_views][field]=views.

  • Eager loading: each populate becomes a db.Preload with its own whitelisted Select, Order, and translated Where. hush relation names are CamelCased to GORM field names ("author" → "Author").

  • Errors: translation errors (unknown relation, depth exceeded) are recorded on the statement via db.AddError and surface on db.Error when the query runs, matching GORM conventions.

MongoDB adapter

hush/mongo is a first-class adapter: a validated query translates to MongoDB bson filter/projection/sort documents and aggregation pipelines, tested against the in-memory mtest server and a real mongod.

import hushmongo "github.com/DhimasYulian/hush/mongo"

q, err := hush.Parse(values, schema)
if err != nil { /* ... */ }

// Find path: filter + projection/sort/pagination as find options.
cur, err := coll.Find(ctx, hushmongo.Filter(q), hushmongo.FindOptions(schema, q))

// Aggregate path: $match/$sort/$skip/$limit/$group/$lookup pipeline, or a
// $facet pipeline returning results and an exact total count in one call.
pipe, err := hushmongo.Pipeline(schema, q)
facet, err := hushmongo.PipelineFacet(schema, q)

The translator covers every hush operator (typed values, regex metacharacter escaping, logical $and/$or/$nor grouping), whitelisted projection and sort, $group with count/sum/avg aggregations, and nested $lookup for populates — with per-relation whitelists and max-depth enforcement.

A complete walkthrough — schema, parse, translated filter, find options, and pipelines — is available as the runnable mongo.Pipeline example.

Translation notes
  • Conventions: related collections are named relation+"s" (e.g. author → authors) and joined on relation+"_id" local fields against the foreign _id. All four are configurable on a hushmongo.Translator if your schema differs.

    t := hushmongo.Translator{
    	CollectionName: func(rel string) string { return "usr_" + rel },
    	LocalField:     func(rel string) string { return rel + "Id" },
    	ForeignField:   "key",
    }
    pipe, err := t.Pipeline(schema, q)
    
  • Pagination & has-more: pagination[withCount] defaults to true, so the Find path requests limit+1 documents and you detect a next page the same way as with GORM:

    hasMore := len(docs) > limit
    

    The $facet path returns the exact count instead: decode the single result document's results and totalCount keys.

  • Projection: requesting fields excludes _id (SELECT fields parity); the foreign _id is always retained inside $lookup projections so nested joins keep matching.

  • Errors: translation errors (unknown relation, depth exceeded) are returned by Pipeline/PipelineFacet, and Filter/Projection/Sort silently skip fields that failed validation earlier.

Example

The _example/ directory contains the official porting contract for integrating hush with a database or query builder that does not yet have a first-class adapter. Its main.go demonstrates every hush feature and teaches the filter-walker pattern a new adapter must support:

go run ./_example

See _example/README.md for details on the porting contract.

License

hush is released under the MIT License.

Documentation

Overview

Package hush parses, builds, and validates structured query strings from URL parameters.

Overview

hush processes URL query strings through a three-stage pipeline:

Parse → Build → Validate → *Query

Given a URL query string like:

filters[title][$containsi]=go&sort[0]=createdAt:desc&fields[0]=title

hush produces a typed Query value with structured Filters, Fields, Sort, Pagination, and Populates — validated against a user-defined Schema.

Entrypoints

The two main entrypoints are:

Schema Definition

Use NewSchema and the builder methods to declare what is allowed:

schema, err := hush.NewSchema("article").
    Filterable("title", hush.TypeString, hush.OpEq, hush.OpContainsi).
    Filterable("views", hush.TypeNumber, hush.OpGt).
    Sortable("title", "createdAt").
    Selectable("title", "body", "createdAt").
    Relation("author", authorSchema, 5).
    MaxLimit(100).
    Build()

Query String Syntax

The expected query string format uses bracket notation:

filters[field][$operator]=value          — filter conditions
filters[$and][0][field][$operator]=value — AND combinators
filters[$or][0][field][$operator]=value  — OR combinators
filters[$not][field][$operator]=value    — NOT combinator
fields[0]=fieldName                      — field selection
sort[0]=fieldName:desc                   — sorting (asc or desc)
groupBy[0]=fieldName                     — group by field
aggregations[name][func]=count           — aggregate function (count, sum, avg)
aggregations[name][field]=fieldName      — field to aggregate on
pagination[start]=0                      — offset
pagination[limit]=25                     — page size
pagination[withCount]=true               — include total row count (default true)
populate[0]=relationName                 — include relations
populate[relation][fields][0]=name       — nested field selection
populate=*                               — populate all relations

Error Handling

Parse and build errors fail fast (first error). Validation errors accumulate across all query sections and are returned together via errors.Join.

All errors can be inspected with errors.Is against the exported sentinel values (e.g. ErrUnknownField, ErrOperatorNotAllowed). Structured error context is available via errors.As with the *Error type.

Index

Examples

Constants

View Source
const (
	OpEq = query.OpEq
	OpNe = query.OpNe

	OpGt  = query.OpGt
	OpGte = query.OpGte

	OpLt  = query.OpLt
	OpLte = query.OpLte

	OpIn      = query.OpIn
	OpNotIn   = query.OpNotIn
	OpBetween = query.OpBetween

	OpContains   = query.OpContains
	OpContainsi  = query.OpContainsi
	OpStartsWith = query.OpStartsWith
	OpEndsWith   = query.OpEndsWith

	OpNull    = query.OpNull
	OpNotNull = query.OpNotNull
)

Comparison operators.

View Source
const (
	SortAsc  = query.SortAsc
	SortDesc = query.SortDesc
)

Sort directions.

View Source
const (
	TypeString = schema.TypeString
	TypeNumber = schema.TypeNumber
	TypeBool   = schema.TypeBool
	TypeDate   = schema.TypeDate
)
View Source
const AbsoluteMaxLimit = schema.AbsoluteMaxLimit

AbsoluteMaxLimit is the hard upper bound for pagination limits.

View Source
const DefaultMaxLimit = schema.DefaultMaxLimit

DefaultMaxLimit is the default maximum pagination limit.

Variables

View Source
var (
	ErrEmptyKey            = parse.ErrEmptyKey
	ErrEmptySegment        = parse.ErrEmptySegment
	ErrInvalidSyntax       = parse.ErrInvalidSyntax
	ErrUnexpectedCharacter = parse.ErrUnexpectedCharacter
)

Parse phase errors.

View Source
var (
	ErrInvalidFields  = build.ErrInvalidFields
	ErrInvalidSort    = build.ErrInvalidSort
	ErrInvalidFilters = build.ErrInvalidFilters
	ErrInvalidGroupBy = build.ErrInvalidGroupBy
)

Build phase errors.

View Source
var (
	ErrEmptyName         = schema.ErrEmptyName
	ErrNoOperators       = schema.ErrNoOperators
	ErrUnknownOperator   = schema.ErrUnknownOperator
	ErrDuplicateField    = schema.ErrDuplicateField
	ErrDuplicateRelation = schema.ErrDuplicateRelation
	ErrNilTarget         = schema.ErrNilTarget
	ErrInvalidMaxDepth   = schema.ErrInvalidMaxDepth
	ErrInvalidMaxLimit   = schema.ErrInvalidMaxLimit
	ErrUnknownFieldType  = schema.ErrUnknownFieldType
)

Schema builder errors.

View Source
var (
	ErrInvalidPath        = validate.ErrInvalidPath
	ErrUnknownField       = validate.ErrUnknownField
	ErrOperatorNotAllowed = validate.ErrOperatorNotAllowed
	ErrNestingTooDeep     = validate.ErrNestingTooDeep
	ErrInvalidValue       = validate.ErrInvalidValue
	ErrUnknownFilterNode  = validate.ErrUnknownFilterNode
	ErrMissingSchema      = validate.ErrMissingSchema
	ErrUnknownGroupBy     = validate.ErrUnknownGroupBy
)

Validation phase errors.

View Source
var (
	ErrInvalidPopulate    = query.ErrInvalidPopulate
	ErrInvalidPagination  = query.ErrInvalidPagination
	ErrInvalidAggregation = query.ErrInvalidAggregation
)

Shared cross-domain errors.

Functions

func Coerce

func Coerce(t FieldType, raw string) (any, error)

Coerce parses a raw filter value string according to the given field type, returning a string for TypeString, a float64 for TypeNumber, a bool for TypeBool, and a time.Time for TypeDate. The parsed Query already carries these coerced values on each Condition.Values, so most adapters never need to call this directly.

func EscapeLike

func EscapeLike(s string) string

EscapeLike escapes LIKE wildcard characters in a literal value so that user input is matched literally rather than interpreted as a pattern. It escapes the backslash, percent, and underscore characters using a backslash escape.

Adapters must wrap the escaped value with the appropriate '%' placeholders for the pattern operators:

$contains:   "%" + EscapeLike(v) + "%"
$startsWith: EscapeLike(v) + "%"
$endsWith:   "%" + EscapeLike(v)

func IsNotNullOperator

func IsNotNullOperator(op Operator) bool

IsNotNullOperator reports whether the operator is $notNull, which maps to SQL's IS NOT NULL. NULL operators carry no coerced values (Condition.Values is nil).

func IsNullOperator

func IsNullOperator(op Operator) bool

IsNullOperator reports whether the operator is $null, which maps to SQL's IS NULL. NULL operators carry no coerced values (Condition.Values is nil).

Types

type Aggregation

type Aggregation = query.Aggregation

Aggregation specifies a computed aggregate function with an output alias.

type And

type And = query.And

And combines multiple filters with logical AND.

type Condition

type Condition = query.Condition

Condition is a leaf filter: a field path + operator + value(s).

type Error

type Error = query.Error

Error is a structured validation error with context about what failed.

type Field

type Field = query.Field

Field is a string-typed field name.

type FieldDef

type FieldDef = schema.FieldDef

FieldDef describes a filterable field: its name, type, and allowed operators.

type FieldType

type FieldType = schema.FieldType

FieldType represents the data type of a filterable field.

type Filter

type Filter = query.Filter

Filter is the interface implemented by Condition, And, Or, and Not.

type Not

type Not = query.Not

Not negates a single filter.

type Operator

type Operator = query.Operator

Operator is a string-typed filter comparison operator.

type Or

type Or = query.Or

Or combines multiple filters with logical OR.

type Pagination

type Pagination = query.Pagination

Pagination holds optional start/limit values.

type Path

type Path = query.Path

Path is a slice of strings representing a dotted/bracket field path.

type Populate

type Populate = query.Populate

Populate specifies a relation to include, with optional nested options.

type Query

type Query = query.Query

Query is the root result of parsing and validating query parameters.

func Parse

func Parse(values url.Values, root *Schema) (*Query, error)

Parse processes URL query values through the three-stage pipeline (parse → build → validate) and returns a validated Query.

Example
package main

import (
	"fmt"
	"net/url"

	"github.com/DhimasYulian/hush"
)

func main() {
	schema, err := hush.NewSchema("article").
		Filterable("title", hush.TypeString, hush.OpEq, hush.OpContainsi).
		Sortable("createdAt").
		Selectable("title", "body").
		MaxLimit(100).
		Build()
	if err != nil {
		panic(err)
	}

	values := url.Values{
		"filters[title][$containsi]": {"go"},
		"sort[0]":                    {"createdAt:desc"},
		"fields[0]":                  {"title"},
		"pagination[limit]":          {"25"},
	}

	query, err := hush.Parse(values, schema)
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println("filter field:", query.Filters.(hush.Condition).Path[0])
	fmt.Println("sort dir:", query.Sort[0].Direction)
	fmt.Println("fields:", query.Fields)
	fmt.Println("limit:", *query.Pagination.Limit)
}
Output:
filter field: title
sort dir: desc
fields: [title]
limit: 25

type RelationDef

type RelationDef = schema.RelationDef

RelationDef describes a named relation to another schema with a max nesting depth.

type RelationOption

type RelationOption func(*RelationDef)

RelationOption configures a relation declaration.

func Hidden

func Hidden() RelationOption

Hidden marks a relation as hidden from wildcard populate (populate=*).

type Schema

type Schema struct {
	// contains filtered or unexported fields
}

Schema defines the allowed query operations for a resource. Built via SchemaBuilder.

func (*Schema) Aggregatable

func (s *Schema) Aggregatable(name string) bool

Aggregatable reports whether the field can be used in aggregations.

func (*Schema) Filterable

func (s *Schema) Filterable(name string) (FieldDef, bool)

Filterable returns the field definition if the field is filterable.

func (*Schema) Groupable

func (s *Schema) Groupable(name string) bool

Groupable reports whether the field can be used in groupBy.

func (*Schema) Inner

func (s *Schema) Inner() *schema.Schema

Inner returns the underlying schema definition. It is exposed for integrations (such as the hush/gorm adapter) that need to walk relations and their nested targets directly.

func (*Schema) MaxLimit

func (s *Schema) MaxLimit() int

MaxLimit returns the maximum pagination limit allowed by this schema.

func (*Schema) Name

func (s *Schema) Name() string

Name returns the schema's resource name.

func (*Schema) Relation

func (s *Schema) Relation(name string) (RelationDef, bool)

Relation returns the named relation definition if it exists.

func (*Schema) Relations

func (s *Schema) Relations() map[string]RelationDef

Relations returns a copy of all declared relations.

func (*Schema) Selectable

func (s *Schema) Selectable(name string) bool

Selectable reports whether the field can be selected.

func (*Schema) SelectableFields

func (s *Schema) SelectableFields() []string

SelectableFields returns all selectable field names in sorted order.

func (*Schema) Sortable

func (s *Schema) Sortable(name string) bool

Sortable reports whether the field is sortable.

type SchemaBuilder

type SchemaBuilder struct {
	// contains filtered or unexported fields
}

SchemaBuilder constructs a Schema with accumulated validation errors. Call Build to finalize and check for errors.

func NewSchema

func NewSchema(name string) *SchemaBuilder

NewSchema creates a new SchemaBuilder with the given resource name.

Example
package main

import (
	"fmt"

	"github.com/DhimasYulian/hush"
)

func main() {
	schema, err := hush.NewSchema("article").
		Filterable("title", hush.TypeString, hush.OpEq, hush.OpContainsi).
		Filterable("views", hush.TypeNumber, hush.OpGt, hush.OpLt).
		Sortable("title", "createdAt").
		Selectable("title", "body", "createdAt").
		MaxLimit(100).
		Build()
	if err != nil {
		panic(err)
	}

	fmt.Println("name:", schema.Name())
	fmt.Println("max limit:", schema.MaxLimit())

}
Output:
name: article
max limit: 100

func (*SchemaBuilder) Aggregatable

func (b *SchemaBuilder) Aggregatable(names ...string) *SchemaBuilder

Aggregatable declares fields as aggregatable (available for aggregations).

func (*SchemaBuilder) Build

func (b *SchemaBuilder) Build() (*Schema, error)

Build finalizes the schema and returns any accumulated validation errors.

func (*SchemaBuilder) Filterable

func (b *SchemaBuilder) Filterable(name string, t FieldType, ops ...Operator) *SchemaBuilder

Filterable declares a field as filterable with a type and set of allowed operators.

func (*SchemaBuilder) Groupable

func (b *SchemaBuilder) Groupable(names ...string) *SchemaBuilder

Groupable declares fields as groupable (available for groupBy).

func (*SchemaBuilder) MaxLimit

func (b *SchemaBuilder) MaxLimit(n int) *SchemaBuilder

MaxLimit sets the maximum allowed pagination limit. Must be between 1 and AbsoluteMaxLimit.

func (*SchemaBuilder) Relation

func (b *SchemaBuilder) Relation(name string, target *Schema, maxDepth int, opts ...RelationOption) *SchemaBuilder

Relation declares a named relation to another schema with a max nesting depth.

func (*SchemaBuilder) Selectable

func (b *SchemaBuilder) Selectable(names ...string) *SchemaBuilder

Selectable declares fields as selectable (available for field selection).

func (*SchemaBuilder) Sortable

func (b *SchemaBuilder) Sortable(names ...string) *SchemaBuilder

Sortable declares fields as sortable.

type Sort

type Sort = query.Sort

Sort specifies a field path and direction for ordering.

type SortDirection

type SortDirection = query.SortDirection

SortDirection is a string-typed sort direction ("asc" or "desc").

type Value

type Value = query.Value

Value is a slice of strings representing one or more filter values.

Directories

Path Synopsis
Package main demonstrates ALL hush features by walking a comprehensive query.
Package main demonstrates ALL hush features by walking a comprehensive query.
Package gorm translates validated hush queries into GORM clauses so a consumer can integrate hush with gorm by importing hush/gorm and using db.Scopes without writing any per-operator code.
Package gorm translates validated hush queries into GORM clauses so a consumer can integrate hush with gorm by importing hush/gorm and using db.Scopes without writing any per-operator code.
internal
coerce
Package coerce converts raw filter value strings to their schema-declared Go types so query adapters can bind values without re-parsing them.
Package coerce converts raw filter value strings to their schema-declared Go types so query adapters can bind values without re-parsing them.
Package mongo translates validated hush queries into MongoDB bson documents and aggregation pipelines so a consumer can integrate hush with the official MongoDB Go driver without writing any per-operator code.
Package mongo translates validated hush queries into MongoDB bson documents and aggregation pipelines so a consumer can integrate hush with the official MongoDB Go driver without writing any per-operator code.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL