1

So I was having a discussion with some co-workers, imagine I'm designing an API. The API takes in a list of IDs, and returns a list of corresponding objects for each ID, each ID corresponds to exactly 1 object, and if any ID is not found the entire call fails. The objects returned do not have the ID used to query for them, but are returned in the same order as the elements passed to the API.

ie 1,3,5 -> obj-1,obj-3,obj-5

So my question is, if this is well documented in the API, that the caller knows which item corresponds to each ID because they are passed in the same order. It seems like inherently bad design to have the only thing that ties the input back to the result is the order, but a co-worker insists this is a common practice in APIs that take in lists of inputs.

Is there anything inherently bad about designing an API like this?

2
  • Queues essentially return items in the same order in which they were presented to the queue. So it's not exactly without precedent. Mar 8, 2018 at 4:45
  • 4
    I'd be strongly tempted to add the id as a field in the returned object, if that doesn't cause significant problems. That way you have redundancy, plus, if a few IDs fail you could still return a partial list.
    – user949300
    Mar 8, 2018 at 6:03

2 Answers 2

6

Result order is a very strict agreement and makes the API less flexible.

What will happen, if there is no data for id? So my suggestion is to return a collection with id : data pairs:

{
  "1" : "obj-1",
  "2" : "obj-2",
  "3" : null,
  "4" : "obj-4"
}

Or if you have multiple data for an id:

{
  "1" : ["obj-1a", "obj-1b"],
  "2" : ["obj-2"],
  "3" : [],
  "4" : ["obj-4"]
}
0

Actually, it's bad design, if an API is implementing implicite behavior. If you consider interfaces and method signatures as contract (like, I guarantee that you will get a list, if you give me a list) to the caller e.g.

public IList<SomeClass> GetAListForAList(IList<int> inputList)
{
    // some code here ...
}

If you consider every public method as black box then you cannot rely on a commitment made a few weeks ago. If you put it more long term...the interface aka method signature did not change. But what about the implementation?

So IMHO it's much better to provide a full contract by the interface aka method signature. E.g.

public IDictionary<int, SomeClass> GetAListForAList(IList<int> inputList)
{
   // some  code here
}

Now you don't have to think about the order. Of course you should think about the null case described by dit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.