sborpo
sborpo

Reputation: 948

Passing "tuples" in a query string for filtering in a REST API

I have a Flask based GET Api endpoint that allows to fetch employees information.

Our client asked to add a "tuple" list filter parameters on the "first name" and "last name" fields, so he can specify first-last name tuples - for example: [("Ben","Long"), ("John", "Miller"), ....]

The results should not show records like ("Ben","Miller") or ("John","Long"), so these fields need to be somehow interconnected in the query parameters.

I see number of options here:

  1. Add 2 list parameters "firstNameTup","lastNameTup" and ask the client to "unzip" the tuples into these two lists, so on the server they will be zipped backed together.
  2. Add one json based parameter and ask the client to create a list of objects [{"first" : "...", "last" : ""}, ...] and encode them in base64 string.
  3. Saying to client "No" and moving the burden of filtering out "unmatched" tuples from the result to him.

Is there any other good way to implement this? whats your recommendation?

Thanks!

Upvotes: 1

Views: 2985

Answers (1)

Eliran Shem Tov
Eliran Shem Tov

Reputation: 628

I think that there are thousands of valid solution for that problem (as I understood it).

IMO, an API server should supply the most flexible AND readable service possible, (easy to be understood by both client developers and server side's new developers that would join the team), so other clients would be able to consume it in the future.

The flask-restless's approach is very flexible, yet strict and I adopted it, even though the project hasn't been maintained for a long time now. Since it's not maintained, I wouldn't use it now, however, I think that the filtering logic implemented there is very solid.

The filtering parameters that this project expects to get from the client are somewhat cumbersome, though it covers most of the cases I could think of.

A single filter object looks like this:

{"name": <fieldname>, "op": <operatorname>, "val": <argument>}

Where name could be "first_name" "last_name" or any other entity attribute. op could be '==', '!=', etc. and val is the value to be filtered.

And a full request's filter object can look like this:

{"or": [<filterobject>, {"and": [<filterobject>, ...]}, ...]}

So a request could look like this:

GET /api/person?q={"filters":[{"or":[{"name":"age","op":"==","val":10},{"name":"age","op":"!=","val":20}]}]} HTTP/1.1

I would explore their search-format documentation in order to grasp the idea, and if you decide to go for it, I would use the actual code that extract's the filters (since its open-source and available in GitHub)

Upvotes: 1

Related Questions