Skip to content

v2 API: Adding new row to table via request is hard to figure out #2237

@OrakMoya

Description

@OrakMoya

Is your feature request related to a problem? Please describe.

The OCS API description for route /ocs/v2.php/apps/tables/api/2/{nodeCollection}/{nodeId}/rows simply states that new row data is { "data": "string" } , going into no detail.

The v1 api for getting rows returns rows in this structure:

"data": [
    {
        "columnId": int,
        "value": string
    },
    ...
]

This leads me to assume that the API for storing a new row expects the same structure. It doesn't, failing with this error in Nextcloud logs: Column with id 0 is not part of table with id 7

Visiting lib/Controller/RowOCSController.php, the create() method has a PHPDoc indicating: $data An array containing the column identifiers and their values. This is misleading as a PHP array is not the same as a JavaScript array, which the method isn't expecting in it's decoded JSON.

The code that extracts the column IDs and their values currently looks like this:

// lib/Controller/RowOCSController.php:74
$newRowData = new RowDataInput();
foreach ($data as $key => $value) {
	$newRowData->add((int)$key, $value);
}

This route actually expects data as a PHP array that has keys as the column IDs and the value at key with the value of the array. This means that the JSON representing the data "array" is not an array but a JavaScript object:

"data": {
    "columnId": "value"
}

Describe the solution you'd like

Expand the docs to specify the correct data structure:

...
data: A PHP array, or a JSON object, containing column IDs as keys and column values as value at key.
...

Request body
Example value
"data": {
    "columnId1": "value",
    "columnId2": "value"
}

Also, return the error in the error message of the response. Currently, it fails with An unexpected error occurred. More details can be found in the logs. Please reach out to your administration. It'd be nicer to return a Column with id .. not found

Describe alternatives you've considered

Rewrite the method to accept data in this format:

"data": [
    {
        "columnId": int,
        "value": string
    },
    ...
]

e.g.:

$newRowData = new RowDataInput();
foreach ($data as $columnData) {
	$newRowData->add((int)$columnData["columnId"], $columnData["value"]);
}

or, even better, to avoid numeric IDs (maybe on another route):

"data": [
    {
        "columnName": string,
        "value": string
    },
    ...
]

Both variants above also play nicer with strict typing.

Accepting the column name instead of the ID allows for easier usage of the API, since I don't have to perform some initial GET request to find out the column IDs and what goes where is easily visible in the code that performs the API request.

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    0. Needs triagePending approval or rejection. This issue is pending approval.enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions