REST URL design for greater than, less than operations
Solution 1
Pagination, greaterthan and lessthan, sound like query parameter to me, since you are queries your resource with these parameters. So you should do something like:
/customers?page=1, or
/customers?page=1>=716, or
/customers?page=1>=716<=819
You can even limit size of page:
/customers?page=1>=716<=819&maxpagesize=100
where gt stands for greater than (same as in xml-escaping) and lt stands for less than.
Solution 2
If you have multiple parameters and need to apply some conditions for each params, I recommend you to pass a JSON object to params.
Consider you want to do a condition for id
and the page
:
/customers?id={"lt": 100, "gt": 30}&page={"start": 1, "size": 10}
It says that I want customers that have Id(s) less than 100 and greater than 30 in the page 1 and page number of 10.
So now simply if you want to apply another condition for other parameters, you can do it by:
/customers?id={"lt": 100, "gt": 30}&children={"lt": 5, "gt": 2}&page={"start": 1, "size": 10}
and this query means customers with Id(s) less than 100 and greater than 30, children less than 5 and greater than 2 in the page number 1 with page size of 10.
I highly recommend you to read this document about designing RESTful API: http://blog.luisrei.com/articles/rest.html
Solution 3
@Julio Faerman:
Well, the problem starts when you get multiple parameters. Imagine the query string for "Customers older than 18 and younger than 60 with more than 2 children".
You can define whatever query parameters you like, such as:
/customers?min-age=19&max-age=59&min-children=3
in my example min and max are integers and are inclusive. You can change that if you prefer. Remember, anything in the URI connotes part of the resource identifier. My personal view is that things after the ?
equate to clauses in the WHERE
part of an SQL query (plus ORDER BY
and LIMIT
, not shown here):
SELECT * FROM customers WHERE age>=19 AND age<=59 AND children>=3
Edit:
Instead of min-
and max-
prefixes, you could allow >
, <
(and maybe !
) as the final character of the parameter name, so instead of min-age
you have a parameter called age>
, which, when combined with a value in the query string, ends up looking like age>=19
:-)
Obviously you can only use this trick when the comparison has an equals sign in it.
Solution 4
REST is an architectural style that should not be considered as specific to HTTP. The pattern of the URIs are not what makes an architecture RESTful.
With that said, you probably would want to make your URI so that these queries come as query parameters at the end of the string, e.g.
/customers?min=0&max=76
Solution 5
Here is how I have been doing it.
Let's say you have the field age which is a number.
This is what the urls would look like
Equals: /filter/age=5
Greater Than: /filter/age[gt]=5
Greater Than Equals: /filter/age[gte]=5
Less Than: /filter/age[lt]=5
Less Than Equals: /filter/age[lte]=5
Not Equals: /filter/age[ne]=5
Then when I pass these arguments to the back-end I have a script that just parses the key out and converts it to the correct filter based on the age[INSERT_OPERATOR_HERE]
Vidar
20 years a GIS Developer. I develop mostly C# based applications, WPF and have dabbled with MVC, Blazor technologies. I also tend to use Python to get things done quickly e.g. making changes or extracting data out of Postgres databases.
Updated on July 09, 2022Comments
-
Vidar almost 2 years
I am having a bit of difficulty designing a url for a rest service that can handle requests for customers based on pagination as one type of operation or requesting greater than or less than operators as another type of operation. For example:
Pagination:
GET /customers/0/100
This will get 100 customers for page 0.
Greater/Less Than:
I also need a URL design to get customers that have an id greater than n (e.g. lets say 716). How would you incorporate "greater than" or "less than" in a url. I have to bear in mind that characters ">" and "<" are illegal in urls. I think this url design looks odd:
GET /customers/greaterthan/716 GET /customers/lessthan/716
I can't use a range as that would conflict with the pagination pattern specified above and is not a nice solution in any case e.g.:
GET /customers/716/999999999999 GET /customers/0/716
I'm sure that I'm missing something obvious - does anyone have a better solution?
-
UVM over 13 yearshow do you plan to implement this in real time scenario--just for curiosity
-
Vidar over 13 yearsit's being done using the Restlet framework in Java. Essentially, I'm querying a database for records.
-
-
Vidar over 13 yearssorry I think I've confused everyone here - I don't mean do pagination and more than, less than operations all at the same time. Pagination is a separate function and the less/greater than is another type of function.
-
Tarlog over 13 yearsIt doesn't matter. Pagination and less/greater are unrelated issues. You should identify your resource. In your case the resource is customers. Both pagination and less/greater are query on the resource, but it's still the same resource. Therefore you should not try to insert your functionality in the url (path-param), but instead you should use query params. At the end your call will reach the same resource class (in java), than you can add your query params to the SQL query or something like this.
-
Vidar over 13 yearsHow would you do greater than 76?
-
Darrel Miller over 13 yearsEven if you put the params in the query string, you are still referring to a different resource. That's ok though. Two different resources can still render portions of the same underlying dataset. Simple rule: If it's a different URL and it doesn't redirect then it is a different resource.
-
pc1oad1etter over 13 yearsI would think these parameters could be optional, you could just put a 'min' parameter.
-
Nicholas Shanks over 11 yearsalso, you should make sure your query string params are always in the same order (assuming they are independent), otherwise /resource?a=1&b=2 is a different resource from /resource?b=2&a=1 and a cached entry for one cannot be returned for the other
-
Opentuned over 11 yearsIt seems Tarlog has provided a good solution here however others might find this a useful resource for API design and practice... apigee.com/about/api-best-practices/all/webcast
-
deitch over 9 yearsI stumbled across this today. What an elegant solution. Unfortunately, it only works for IDs, not for queries, so
/customers/16-25
is fine, because we know that the '-' indicates a range, but if it were query field, it wouldn't work:/customers?name=123-127
is that customers where the value of name is from 123 to 127, or customers who have the name equals the string "123-127"? No way to tell. -
Valentin Rusk almost 9 yearsSeems most reliable way to stick with rest! If they use json in query - then way better to go for mongo query style and POST with x-method-override = get. Otherwise everything arrived after "?" - referred as filtering options.
-
Nicholas Shanks almost 9 years@ValentinRusk I didn't understand that. Can you re-post it in your first language so I can translate myself? Ты русский?
-
Valentin Rusk almost 9 yearsЛучший выбор для REST !!! Если использовать JSON в GET, тогда лучше идти по пути стиля Mongo Query + header: x-method-override. В первом случае, все что приходит после "?" - считается фильтрами.
-
Nicholas Shanks almost 9 years@ValentinRusk Okay, not a question, just a compliment :-) Спасибо!
-
themihai over 7 yearsWhy gt/lt instead of symbols? (<>)
-
Tarlog over 7 years<> are special characters.
-
Shrey over 7 yearsI like this answer. Also check tiny range module for nodejs ( npmjs.com/package/tiny-range ) , you can use this notation as well : ~1,2,3,5~10,20~
-
Yami Odymel over 5 yearsIt looks like an
GET /database?query=SELECT * FROM customers WHERE CustomerNo>=16 AND CustomerNo<=716
endpoint.