REST url for resource collection, which filters resource by attribute not equal to a given value

11,444

Solution 1

One option would be to add an additional query parameter such as gradeOperator in which you could pass the operator to be used when comparing the value against the grade parameter. E.g.,

GET /students?grade=8&gradeOperator=!%3D

!%3D is the URL-encoded form of !=, so your REST API would de-encode the operator and interpret this as grade != 8.

Another approach would be to pass the value and operator in the HTTP request body. Something like this would potentially work (with the body provided in JSON as an example):

GET /students
Content-Type: application/json

{ "grade": {"value": 8, "operator": "!=" } }

That could be nice since you wouldn't have to repeat the word 'grade' in gradeOperator, the operator is simply nested inside a JSON object as the value of grade.

In either solution, you could potentially define any number of operators, including <, >, >=, <=, etc. Just be sure to properly sanitize any input operators your API receives, especially if used in a DB query, to avoid things like SQL injection attacks.

Solution 2

What I am thinking of doing is including the operator as part of the argument, delimited from the value. I would also define non-symbolic operators to avoid the need for ugly URL-encoding or confusion with the equals sign after the parameter name. For your example, this would be something like this for students not in grade 8:

GET /students?grade=neq|8

Students in grades > 8 would be:

GET /students?grade=gt|8

Students between grades 8 and 10 (inclusive):

GET /students?grade=gte|8,lte|10

This approach can be extended to other filterable fields without the need to add additional parameters to modify the way each field is filtered.

Solution 3

Stripe has one of the most respected APIs.

They use a separate parameter for each operator separated with a dot.

For example, to search on created date:

/charges?created.gt=
/charges?created.gte=
/charges?created.lt=
/charges?created.lte=

In your case you could do something like:

/students?grade.gt=8&grade.lt=8

Or even add another operator for not:

/students?grade.not=8
Share:
11,444
Karthik Chandraraj
Author by

Karthik Chandraraj

Developer

Updated on June 24, 2022

Comments

  • Karthik Chandraraj
    Karthik Chandraraj almost 2 years

    How to design REST url for resource collection, which filters resource by attribute not equal to a given value?

    For example, to get the students in 8th grade, we use

    GET /students?grade=8
    

    How to do the same, if we need to get the students not in 8th grade? And how to design for less than (<) , greater than (>) etc ?