Standardising the structure of our JSON reponses
One thing that would be good to clear up is the consistency in the datastructures we return. There’s a widely used convention in putting all primary data within a top-level field called data:
, but we don’t use it. It also means you can nicely put any metadata or secondary data alongside the primary records. We have some inconsistency in this respect.
When rendering multiple objects in a response, we sometimes render the array as the response itself, and sometimes render the array inside a top-level field with the name of the object (which is maybe not a great idea, and it means the field containing the data is different for every endpoint).
So for example, the output of the Api::CustomersController#index
action (here) currently looks like this:
[
<customer 1>,
<customer 2>,
<customer 3>
]
Whereas the Api::OrdersController#index
action (here) currently looks like this:
{
orders: [ # Resources in a top-level field (good) with a changeable name (bad).
<order 1>,
<order 2>,
<order 3>
],
pagination: <pagination data> # Secondary data can be added (good)
}
So the convention would be to return primary records in a data
field, and use that consistently for both single and multiple records, eg:
{
data: <single object or array of objects>,
pagination: <pagination data (for example)>
}
This means secondary metadata can be added in any response. It could be pagination data, or it could be other things. For example, if a record has linked records such as adjustments on a line item, it’s common to return some links to other API endpoints where those records can be accessed.
Also; successful responses should contain the data
field, error responses contain an errors
field, but responses never contain both. I think we already do this errors bit fairly consistently.
How does that sound?