# Work with arrays of JSON objects

A JSON array of objects is one document, while `json_each_row` expects one object for each input row. Choose which representation the destination needs before loading the source. Keeping the whole document and expanding it later can be useful for small request payloads.

```sql
SELECT id, name
FROM json_to_recordset('[{"id":1,"name":"Ada"},{"id":2,"name":"Grace"}]')
AS item(id UInt64, name String)
ORDER BY id
FORMAT csv;
```

## Declare the row contract

The recordset declaration makes the intended column names and types explicit. Test missing fields, nulls and values outside the declared ranges. A flexible source document is not a reason to accept an ambiguous destination schema.

For larger files, convert the outer array to one object per line in the importer and send it with `INSERT ... FORMAT json_each_row`. Do not merely rename the file: the byte representation must actually match the selected format.

If the array is a property inside a retained JSON column, extract that property first and expand its elements with the documented JSON table functions. Preserve a source identifier when one parent document produces several child rows, so later validation can reconcile the expansion.

See [JSON functions](https://coordinatordb.com/docs/reference/functions/regular-functions/json-functions), [JSON loading](https://coordinatordb.com/docs/guides/clickhouse/data-formats/json/loading) and [JSON type](https://coordinatordb.com/docs/reference/data-types/json).
