All Projects → timsolov → rest-query-parser

timsolov / rest-query-parser

Licence: Apache-2.0 License
Query Parser for REST

Programming Languages

go
31211 projects - #10 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to rest-query-parser

Walkable
A Clojure(script) SQL library for building APIs: Datomic® (GraphQL-ish) pull syntax, data driven configuration, dynamic filtering with relations in mind
Stars: ✭ 384 (+1224.14%)
Mutual labels:  query, orm
Elasticsearch
Use SQL statements to query elasticsearch
Stars: ✭ 98 (+237.93%)
Mutual labels:  query, orm
Queryablelist
Python module to add support for ORM-style filtering to any list of items
Stars: ✭ 19 (-34.48%)
Mutual labels:  query, orm
Antlr4
ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files.
Stars: ✭ 11,227 (+38613.79%)
Mutual labels:  parse, parsing
desktop
Extendable calculator for the 21st Century ⚡
Stars: ✭ 85 (+193.1%)
Mutual labels:  parse, parsing
Parjs
JavaScript parser-combinator library
Stars: ✭ 145 (+400%)
Mutual labels:  parse, parsing
Queryql
Easily add filtering, sorting, and pagination to your Node.js REST API through your old friend: the query string!
Stars: ✭ 76 (+162.07%)
Mutual labels:  query, orm
Foundatio.parsers
A lucene style query parser that is extensible and allows modifying the query.
Stars: ✭ 39 (+34.48%)
Mutual labels:  query, parse
uri-query-parser
a parser and a builder to work with URI query string the right way in PHP
Stars: ✭ 38 (+31.03%)
Mutual labels:  query, query-parser
querqy-elasticsearch
Querqy for Elasticsearch
Stars: ✭ 37 (+27.59%)
Mutual labels:  query, query-parser
fefe
Validate, sanitize and transform values with proper TypeScript types and zero dependencies.
Stars: ✭ 34 (+17.24%)
Mutual labels:  parse, parsing
pinipig
🚀 Performant webservice framework
Stars: ✭ 25 (-13.79%)
Mutual labels:  orm, restapi
Pidgin
C#'s fastest parser combinator library
Stars: ✭ 469 (+1517.24%)
Mutual labels:  parse, parsing
Baby squeel
🐷 An expressive query DSL for Active Record 4 and 5
Stars: ✭ 362 (+1148.28%)
Mutual labels:  query, orm
Angourimath
Open-source symbolic algebra library for C# and F#. One of the most powerful in .NET
Stars: ✭ 266 (+817.24%)
Mutual labels:  parse, parsing
Termsql
Convert text from a file or from stdin into SQL table and query it instantly. Uses sqlite as backend. The idea is to make SQL into a tool on the command line or in scripts.
Stars: ✭ 230 (+693.1%)
Mutual labels:  query, parse
python-yamlable
A thin wrapper of PyYaml to convert Python objects to YAML and back
Stars: ✭ 28 (-3.45%)
Mutual labels:  parse, parsing
LeagueReplayParser
C# library which can read some data from a .rofl file, and start a replay in the client. (no longer actively maintained)
Stars: ✭ 20 (-31.03%)
Mutual labels:  parse, parsing
yorm
Automatic object-YAML mapping for Python.
Stars: ✭ 23 (-20.69%)
Mutual labels:  orm
SocketHook
Socket hook is an injector based on EasyHook (win only) which redirect the traffic to your local server.
Stars: ✭ 38 (+31.03%)
Mutual labels:  restapi

Query Parser for REST

Query Parser is a library for easy building dynamic SQL queries to Database. It provides a simple API for web-applications which needs to do some filtering throught GET queries. It is a connector between the HTTP handler and the DB engine, and manages validations and translations for user inputs.

GoDoc Coverage Status

Installation

go get -u github.com/timsolov/rest-query-parser

Idea

The idia to write this library comes to me after reading this article: REST API Design: Filtering, Sorting, and Pagination.

And principles enumerated in article I considered very useful and practical to use in our project with amount of listings with different filtering.

Fast start

See cmd/main.go and tests for more examples.

    package main
    
    import (
        "errors"
        "fmt"
        "net/url"
    
        rqp "github.com/timsolov/rest-query-parser"
    )
    
    func main() {
        url, _ := url.Parse("http://localhost/?sort=+name,-id&limit=10&id=1&i[eq]=5&s[eq]=one&email[like]=*tim*|name[like]=*tim*")
        q, _ := rqp.NewParse(url.Query(), rqp.Validations{
            "limit:required": rqp.MinMax(10, 100),  // limit must present in the Query part and must be between 10 and 100 (default: Min(1))
            "sort":           rqp.In("id", "name"), // sort could be or not in the query but if it is present it must be equal to "in" or "name"
            "s":      rqp.In("one", "two"), // filter: s - string and equal
            "id:int": nil,                  // filter: id is integer without additional validation
            "i:int": func(value interface{}) error { // filter: custom func for validating
                if value.(int) > 1 && value.(int) < 10 {
                    return nil
                }
                return errors.New("i: must be greater then 1 and lower then 10")
            },
            "email": nil,
            "name":  nil,
        })

        fmt.Println(q.SQL("table")) // SELECT * FROM table WHERE id = ? AND i = ? AND s = ? AND (email LIKE ? OR name LIKE ?) ORDER BY name, id DESC LIMIT 10
        fmt.Println(q.Where())      // id = ? AND i = ? AND s = ? AND (email LIKE ? OR name LIKE ?)
        fmt.Println(q.Args())       // [1 5 one %tim% %tim%]

        q.AddValidation("fields", rqp.In("id", "name"))
        q.SetUrlString("http://localhost/?fields=id,name&limit=10")
        q.Parse()

        fmt.Println(q.SQL("table")) // SELECT id, name FROM table ORDER BY id LIMIT 10
        fmt.Println(q.FieldsSQL())  // id, name
        fmt.Println(q.Args())       // []
    }

Top level fields:

  • fields - fields for SELECT clause separated by comma (",") Eg. &fields=id,name. If nothing provided will use "*" by default. Attention! If you want to use this filter you have to define validation func for it. Use rqp.In("id", "name") func for limit fields for your query.
  • sort - sorting fields list separated by comma (","). Must be validated too. Could include prefix +/- which means ASC/DESC sorting. Eg. &sort=+id,-name will print ORDER BY id, name DESC. You have to filter fields in this parameter by adding rqp.In("id", "name").
  • limit - is limit for LIMIT clause. Should be greater then 0 by default. Definition of the validation for limit is not required. But you may use rqp.Max(100) to limit top threshold.
  • offset - is offset for OFFSET clause. Should be greater then or equal to 0 by default. Definition of the validation for offset is not required.

Validation modificators:

  • :required - parameter is required. Must present in the query string. Raise error if not.
  • :int - parameter must be convertable to int type. Raise error if not.
  • :bool - parameter must be convertable to bool type. Raise error if not.

Supported types

  • string - the default type for all provided filters if not specified another. Could be compared by eq, ne, gt, lt, gte, lte, like, ilike, nlike, nilike, in, nin, is, not methods (nlike, nilike means NOT LIKE, NOT ILIKE respectively, in, nin means IN, NOT IN respectively, is, not for comparison to NULL IS NULL, IS NOT NULL).
  • int - integer type. Must be specified with tag ":int". Could be compared by eq, ne, gt, lt, gte, lte, in, nin methods.
  • bool - boolean type. Must be specified with tag ":bool". Could be compared by eq method.

Date usage

This is simple example to show logic which you can extend.

    import (
        "fmt"
        "net/url"
        validation "github.com/go-ozzo/ozzo-validation/v4"
    )

    func main() {
        url, _ := url.Parse("http://localhost/?create_at[eq]=2020-10-02")
        q, _ := rqp.NewParse(url.Query(), rqp.Validations{
            "created_at": func(v interface{}) error {
                s, ok := v.(string)
                if !ok {
                    return rqp.ErrBadFormat
                }
                return validation.Validate(s, validation.Date("2006-01-02"))
            },
        })

        q.ReplaceNames(rqp.Replacer{"created_at": "DATE(created_at)"})

        fmt.Println(q.SQL("table")) // SELECT * FROM table WHERE DATE(created_at) = ?
    }
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].