Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/timsolov/rest-query-parser
Query Parser for REST
https://github.com/timsolov/rest-query-parser
go golang orm parse parser parsing query query-parser rest rest-api restapi sql
Last synced: about 2 months ago
JSON representation
Query Parser for REST
- Host: GitHub
- URL: https://github.com/timsolov/rest-query-parser
- Owner: timsolov
- License: apache-2.0
- Created: 2020-02-10T17:58:42.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2023-12-04T16:29:58.000Z (about 1 year ago)
- Last Synced: 2024-07-31T20:52:47.260Z (4 months ago)
- Topics: go, golang, orm, parse, parser, parsing, query, query-parser, rest, rest-api, restapi, sql
- Language: Go
- Homepage:
- Size: 85 KB
- Stars: 73
- Watchers: 4
- Forks: 21
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-go - rqp - Query Parser for REST API. Filtering, validations, both `AND`, `OR` operations are supported directly in the query. (Query Language / HTTP Clients)
- zero-alloc-awesome-go - rqp - Query Parser for REST API. Filtering, validations, both `AND`, `OR` operations are supported directly in the query. (Query Language / HTTP Clients)
- awesome-go-extra - rest-query-parser - 02-10T17:58:42Z|2022-06-05T20:23:06Z| (Query Language / HTTP Clients)
README
# Query Parser for REST
[![GoDoc](https://godoc.org/github.com/timsolov/rest-query-parser?status.png)](https://godoc.org/github.com/timsolov/rest-query-parser)
[![Coverage Status](https://coveralls.io/repos/github/timsolov/rest-query-parser/badge.svg?branch=master)](https://coveralls.io/github/timsolov/rest-query-parser?branch=master)
[![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome)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.
## 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](https://www.moesif.com/blog/technical/api-design/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.```go
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.Select()) // 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.```go
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) = ?
}
```