Description
I've recently dove into GraphQL and am loving it so far. Being consistent with why GraphQL was made and what it is, it obviously does not supports as it is not a data store. This includes and
/or
s.
However, I have been researching online and was wondering if there is a GraphQL-recommended way of implementing operators. If not, should there be?
I've seen people take a few different approaches, and our team has thought of some of their own, and here are two of our most popular (internally) ideas. I'd love to get feedback on them.
Goal: Allowing developers to be able to specify all operators commonly used and keep consistent/original with GraphQL as much as possible.
- Allow input to be dynamic, either the original type (numbers for number, strings for strings, etc,.) or JSON.
- PROS: Developers can still query for fields naturally most of the time, in the native GraphQL way. It is only when they have to do custom queries that they'll have to write JSON.
- CONS: Input type isn't consistent can provide problems. Fact that we're accepting JSON makes writing the query lengthy and it goes a bit against GraphQL's clean, simple and natural query syntax.
Example:
{
// By default an array is treated like an 'or'
// By default no operator$ defined means an 'and'
case(caseStatus:"[closed, open]", caseNumber:"2012") {
caseNumber
}
}
// Customized
{
// The caseStatus field will be translated into an or where caseStatus can be any of the ones defined in 'val'
// The operator$ field at the end makes this entire evaluation an or as well
// It translates to
// Select * From sys_case Where (caseStatus IN ['closed', 'open']) OR (caseNumber = '2012')
case(caseStatus:"{ val:"[closed, open]", operator$:"or"}", caseNumber:"2012", operator$:"or") {
caseNumber
}
}
- Have a unique
args
orq
object that developers can pass in if they need to do something other than a plain equals. This would be JSON.
- PROS: Fully supports all operators and respects composite conditions ((eval && eval2) || (eval3)
- CONS: Once more, JSON diverges from the clean GraphQL syntax in a way that it makes writing the query complex. And this makes writing the query complex for even simple things, such as
field x = 'y' && field z = 's'
Example:
var conditionOne = {
properties: {
caseNumber: '2',
caseTitle: '3'
}
};
var conditionTwo = {
properties: {
caseCategory: '4',
caseCategory2: '5',
operator: 'or'
}
};
var conditionThree = {
properties: {
caseNumber: 'someVal',
caseStatus: 'someOtherVal',
operator: 'or'
},
operator: 'or'
};
case(args: [conditionOne, conditionTwo, conditionThree]) {
caseNumber
}
// Translates to
// Select *
// From sys_case
// Where (case_number='2' AND case_title='3')
// AND (case_category='4' OR case_category_2='5')
// OR (case_number='someVal' OR case_status='someOtherVal')
In conclusion, the feeling I get is going to JSON is the right route to go, even though it might be unfortunate. Example two seems to be the simplest, and even it is quite a bit of code. Maybe a mix of having support for simple filtering (caseStatus:'something') (caseStatus:'!something') can be done and then for more advanced operators a JSON override in a q
or args
can be specified.
I'd love to hear what the community thinks.