Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to express advanced expressions between query parameters in a REST API?

The problem (or missing feature) is the lack of expression possibility between different query parameters. As I see it you can only specify and between parameters, but how do you solve it if you want to have not equal, or or xor?

I would like to be able to express things like:

All users with age 20 or the name Bosse

/users?age=22|name=Bosse

All users except David and Lennart

/users?name!=David&name!=Lennart

My first idea is to use a query parameter called _filter and take a String with my expression like this:

All users with with age 22 or a name that is not Bosse

/users?_filter=age eq 22 or name neq Bosse

What is the best solution for this problem?

I am writing my API with Java and Jersey, so if there is any special solution for Jersey, let me know.

like image 886
David Berg Avatar asked Nov 09 '15 15:11

David Berg


2 Answers

I can see two solutions to achieve that:

  • Using a special query parameter containing the expression when executing a GET method. It's the way OData does with its $filter parameter (see this link: https://msdn.microsoft.com/fr-fr/library/gg309461.aspx#BKMK_filter). Here is a sample:

    /AccountSet?$filter=AccountCategoryCode/Value eq 2 or AccountRatingCode/Value eq 1
    

    Parse.com also uses such approach with its where parameter but the query is described using a JSON structure (see this link: https://parse.com/docs/rest/guide#queries). Here is a sample:

    curl -X GET \
      -H "X-Parse-Application-Id: ${APPLICATION_ID}" \
      -H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
      -G \
      --data-urlencode 'where={"score":{"$gte":1000,"$lte":3000}}' \
      https://api.parse.com/1/classes/GameScore
    
  • If it's something too difficult to describe, you could also use a POST method and specify the query in the request payload. ElasticSearch uses such approach for its query support (see this link: https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html). Here is a sample:

    $ curl -XGET 'http://localhost:9200/twitter/tweet/_search?routing=kimchy' -d '{
        "query": {
            "bool" : {
                "must" : {
                    "query_string" : {
                        "query" : "some query string here"
                    }
                },
                "filter" : {
                    "term" : { "user" : "kimchy" }
                }
            }
        }
    }
    '
    

Hope it helps you, Thierry

like image 97
Thierry Templier Avatar answered Sep 19 '22 02:09

Thierry Templier


OK so here it is You could add + or - to include or exclude , and an inclusive filter keyword for AND and OR

For excluding
GET /users?name=-David,-Lennart
For including
GET /users?name=+Bossee
For OR
GET /users?name=+Bossee&age=22&inclusive=false
For AND
GET /users?name=+Bossee&age=22&inclusive=true

In this way the APIs are very intuitive, very readable also does the work you want it to do.

EDIT - very very difficult question , however I would do it this way

  GET /users?name=+Bossee&age=22&place=NewYork&inclusive=false,true

Which means the first relation is not inclusive - or in other words it is OR second relation is inclusive - or in other words it is AND

The solution is with the consideration that evaluation is from left to right.

like image 41
Biraj B Choudhury Avatar answered Sep 23 '22 02:09

Biraj B Choudhury