Search code examples
jsonsymfonydartfosrestbundle

Is {0:{"id":1,...},{"id:2,....}} a other reprensation of a JSON list like [{"id":1,...},{"id:2,....}]


I have a little dilema. I have a backend/Frontend Application that comunicates with a JSON based REST Api.

The backend is written in PHP(Symfony/jmsserializer) and the Frontend in Dart

The communication between these two has a little Problem.

For most List Data the backend responds with a JSON like

[{"id":1,...},{"id:2,....}]

But for some it responds with

{"0":{"id":1,...}, "1":{"id:2,....}}

Now my Question is should the backend respond with the later at all or only with the first?


Solution

  • Problem

    You usually have a list of objects. You sometimes get an object with sub-objects as properties.

    Underlying issue

    JS/JSON-Lists are ordered from 0 upwards which means that if you have PHP-Array which does not respect this rule json_encode will output a JS/JSON-Object instead using the numeric indices as keys.

    PHP-Arrays are ordered maps which have more features that the JSON-Lists. Whenever you're using those extra features you won't be able to translate directly into JSON-Lists without loosing some information (ordering, keys, skipped indices, etc.).

    PHP-Arrays and JSON-Objects on the other hand are more ore less equivalent in terms of features and can be correctly translated between each other without any loss of information.

    Occurence

    This happens if you have an initial PHP-Array of values which respects the JS/JSON-List rules but the keys in the list of objects are modified somehow. For example if you have a custom indexing order {"3":{}, "0":{}, "1":{}, "2":{}} or if you have (any) keys that are strings (ie. not numeric).

    This always happens if you want to use the numeric id of the object as the numeric index of the list {"123":{"id": 123, "name": "obj"}} even if the numeric ids are in ascending order... so long as they are not starting from 0 upwards it's not a json-list it's a json-object.

    Specific case

    So my guess is that the PHP code in the backend is doing something like fetching a list of objects but its modifying something about it like inserting them by (string) keys into the array, inserting them in a specific order, removing some of them.

    Resolution

    The backend can easily fix this by using array_values($listOfObjects) before using json_encode which will reindex the entire list by numeric indices of ascending value.