I have an API endpoint that returns some statistics. Currently the response looks like:
Option 1:
{
"stats": [
{
"name": "some-stats-key1",
"value": 10
},
{
"name": "some-stats-key2",
"value": 20
}
],
... other keys
}
But this looks a bit complex and I what to make it like:
Option 2:
{
"stats": {
"some-stats-key1": 10,
"some-stats-key2": 20
}
... other keys
}
I understand that Option 1 is easier to be extended, but less comfortable for users. What other issues I can face using one of these options? Or should I make a hybrid solution like:
Option 3:
{
"stats": {
"some-stats-key1": {
"name": "some-stats-key1",
"value": 10
},
"some-stats-key2": {
"name": "some-stats-key2",
"value": 20
},
},
... other keys
}
The keys "some-stats-key1" and "some-stats-key2" are just internal values and it's expected API user will map them into readable names using documentation. All the keys are unique.
The order of "stats" isn't important.
The typical use case is just to get all the stats, match keys with readable names and show as a table on a web-page. But currently I can't say if no one will need only a part of the stats later.
Is there a best practice for this issue?
Best Answer
I'd go for option 2. If the API consumer will convert
some-stats-key1
into something readable, that probably means he/she has a list of values he/she is interested in (say,some-stats-key1
andsome-stats-key3
), and will iterate over that list. By choosing a JSON object, it will be deserialized as a dictionary/map which provides a convenient lookup for the consumer of the API.This will be more cumbersome with option 1, where the consumer needs to iterate over the JSON array, or pre-create their own dictionary with interesting keys.
Option 3 is a little too verbose for me, the duplication of the key names just doesn't appeal to me.
If extensibility is a concern, you can always publish a v2 of your API returning something like
and keep the v1 for backwards compatibility. Maintaining backwards compatibility within a single version of the API can be a real PITA if you don't have complete control over how the API is consumed. I've seen a consumption of an API of mine 'break' when I just added an extra (optional) key-value pair (i.e. not changing the structure).