REST API JSON – Is It Good Practice to Make API Response List of Values as Dictionary?

apijsonrest

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 and some-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

"stats": {
    "some-stats-key1": { "value": 10, "error-margin": 0.1 },
    "some-stats-key2": { "value": 20, "error-margin": 0.2 }
}

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).