Search code examples
api-design

What would be a good API format for “IS NOT SET” clause?


I have a query API against my service, that looks like this (JSON-ish format):

{
   filter: {
            ,attribute2: [val21, val22]
            ,attribute3: []
   }
}

means effectively, select data WHERE attribute2 in ("val21", "val22") AND attribute3 IS NOT NULL in SQL-ish syntax (meaning, the object being returned has attribute 3 set, but I really don't care what its value is. SQL isn't very good at expressing this of course, as my data is key-value store where a key may be "not set" at all instead of being null valued).

I need to expand this API to be able to express IS NOT SET predicate, and I'm at a loss as to what a good way to do so would be.

The only thing I can possibly think of is to add a special "NOT_SET" value in the request API, that would produce NOT SET semantics; but it seems really klunky and hard to grasp:

The API syntax can be thought of as JSON as far as its expressiveness/capability

An ideal answer would reference some well accepted rules on API design, to show that it's "good".

{
   filter: {
            ,attribute2: [val21, val22]
            ,attribute4: [__NOT_SET__]
   }
}

Solution

  • My suggestion would be to move away from trying to use a key-value pair to represent a predicate phrase. You should have a lot more flexibility with a structure similar to:

    {
        filters: [
          { attribute: "attribute2", verb: "IN", values: [val21, val22] },
          { attribute: "attribute2", verb: "NOT IN", values: [val21, val22] },
          { attribute: "attribute4", verb: "IS NOT SET" },
       ]
    }
    

    You'd want an enum of verbs, of course, and values would have to be optional. You can add more verbs later if you need them, and you're no longer putting quite so much pressure on the poor :. You can also provide to the client a list of supported verbs and how many values (if any) of what type they take, so the client can build the UI dynamically, if desired.

    Of course, this is a breaking change, which may or may not be an issue.