Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boolean logic in RESTful filtering and queries

This is sort of a follow-up to someone else's question about filtering/querying a list of cars. There the recommendation for a RESTful filtering request was to put filter expressions in the query of the URI, like this:

/cars?color=blue&type=sedan&doors=4

That's fine. But what if my filtering query becomes more complicated and I need to use Boolean operators, such as:

((color=blue OR type=sedan) AND doors=4) OR color=red

That is, I want to find a four-door blue car or a four-door sedan, but if the car is red I'll take it without caring about any of the other properties.

Is there any sort of convention for providing Boolean expressions in a RESTful URI's query parameters? I suppose I could by create some new querying expression language and put it in a POST, but that seems like a heavy and proprietary approach. How are others solving this?

like image 890
Garret Wilson Avatar asked Sep 09 '14 15:09

Garret Wilson


People also ask

Which Boolean operator is used to filter your search?

AND, OR, NOT. There are three basic Boolean search commands: AND, OR and NOT. AND searches find all of the search terms. For example, searching on dengue AND malaria AND zika returns only results that contain all three search terms.

What are the 3 Boolean logic?

The three basic boolean operators are: AND, OR, and NOT.

What is filtering in REST API?

SAS REST APIs: Filtering. Filtering is the application of a Boolean condition against a collection of resources in order to subset the collection to ony those resources for which the condition is true. (For those familiar with SQL, filtering is analogous to a SQL query with a WHERE clause.)


2 Answers

It is perfectly okay to use

/cars/color:blue/type:sedan/doors:4

instead of

/cars?color=blue&type=sedan&doors=4

The URL standard says only that the path should contain the hierarchical part, and the query should contain the non-hierarchical. Since this is a map-reduce, using / is perfectly valid.

In your case you need a query language to describe your filters. If I were you I would copy an already existing solution, for example the query language of a noSQL database which has a REST API.

  • I think resource query language is what you need. I think you could use it like this:

     /sthg?q="(foo=3|foo=bar)&price=lt=10"
    

or forget the default queryString parser, and like this:

    /sthg?(foo=3|foo=bar)&price=lt=10

I suggest you to read the manual for further details.

  • Since I found no other URL compatible query language (yet), I think the only other option to serialize another query language and send it in a param, like SparSQL

     http://localhost:8003/v1/graphs/sparql?query=your-urlencoded-query
    

    by marklogic7. Hydra defines a freeTextQuery in its vocab, so they follow the same approach. But I'll ask Markus about this. It's a complicated topic, since according to the self-descriptive messages constraint you should describe somewhere what type of query language you use in the URL. I am not sure about this. :S

conclusion:

In order to support ad-hoc search queries we need a standard way to describe them in the link meta-data. Currently there are only a few standards about this. The most widely used standard is URI templates which does not support nested statements, operators, etc... for what I know. There is a draft called link descriptions which tries to fill the gap, but it is incomplete.

One possible workaround to define an URI template with a single q parameter which has rdf:type of x:SearchQuery and rdfs:range of xsd:string, and create another vocab about how to describe such a x:SearchQuery. After that the description could be used to build search forms, and validate queries sent to the server. Already existing queries could be supported too with this approach, so we don't need a new one.

So this problem can be solved with vocabs or new URI template standards.

like image 76
inf3rno Avatar answered Oct 19 '22 00:10

inf3rno


I have seen many use a query string as you have provided - much like a SQL query string.

Here are just two examples:

  • Socrata (Open Data Portal company)'s SoQL (SQL variant): http://dev.socrata.com/consumers/cookbooks/querying-block-ranges.html
  • openFDA (API from fda.gov for open data) uses a similar string-based query parameter which maps to ElasticSearch queries, I believe: https://open.fda.gov/api/reference/#query-syntax
like image 39
Mark Silverberg Avatar answered Oct 19 '22 01:10

Mark Silverberg