We need to choose an API design for the JSON payload that developers will use to query datasets. We have two competing proposals. Both work just as well. Your objective is to solve the challenge below and then pick the API you think is better and explain why (or recommend a better one).
Given the following SQL statement...
select *
from `users`
where (
`first_name` = 'Taylor'
and `last_name` <> 'McGann'
and (
`age` < 20
or (
`age` >= 30
and `age` < 40
)
or `age` >= 50
)
)
order by `first_name` asc, `age` desc
limit 5000
offset 0;
...construct two separate but identically functional JSON payloads based on the APIs below (i.e. one payload should use API A and the other should use API B). The JSON payloads you construct are essentially translations of the SQL statement above.
For brevity, the API documentation below is not comprehensive and does not include an API "grammar" that outlines all possible expressions. Instead, each section offers two examples of the respective API syntax. You'll notice that API A makes use of more array literals and API B makes use of more object literals. This is the most significant difference and is what we are most interested in evaluating.
At the end of this document is a list of all the operators you would need to construct your two JSON payloads.
Example 1:
{
"condition": [ "firstName", "_eq", "Taylor" ]
}
Example 2:
{
"offset": 2000,
"limit": 1000,
"condition": {
"_and": [
[ "firstName", "_eq", "Taylor" ],
[ "age", "_gte", 30 ]
]
},
"orderBy": [
[ "lastName", "asc" ]
]
}
Example 1:
{
"condition": {
"column": "firstName",
"operator": "_eq",
"value": "Taylor"
}
}
Example 2:
{
"offset": 2000,
"limit": 1000,
"condition": {
"operator": "_and",
"value": [
{
"column": "firstName",
"operator": "_eq",
"value": "Taylor"
},
{
"column": "age",
"operator": "_gte",
"value": 30
}
]
},
"orderBy": [
{
"column": "lastName",
"order": "asc"
}
]
}
_and
_or
_eq
_neq
_gt
_gte
_lt
_lte
_contains
_ncontains
_in
_nin
My stab:
A
B
Review
I like style B better. I like the explicitness of objects, even though they are considerably less terse. I also feel like if we decide to add things to certain operators it's easier to do it under a property name than an index into an array. Something that I think could be useful is a way to specify multiple operators for a single column but I'm not sure how this would work (maybe
_or
and_and
blocks could have an optionalcolumn
field). Additionally I think thatcondition
should be an array that is implicitly thevalue
of an_and
block.