{"html_url": "https://github.com/simonw/datasette/issues/1868#issuecomment-1294003701", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1868", "id": 1294003701, "node_id": "IC_kwDOBm6k_c5NIO31", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-10-27T20:02:26Z", "updated_at": "2022-10-27T20:02:26Z", "author_association": "OWNER", "body": "The problem with the above design is that I want to support a bunch of different actions that can be taken against a table:\r\n- insert a single row\r\n- insert multiple rows\r\n- bulk update rows\r\n- rename table\r\n- alter table\r\n- drop table\r\n\r\nI could have ALL of those be a `POST /db/table` with different JSON root keys (`{\"drop\": true}` for example, but this raises two problems:\r\n\r\n1. Server logs that only show `POST /db/table` will be less useful, they won't reveal what action was performed\r\n2. What happens if you send `{\"insert\": {\"title\": \"New record\"}, \"drop\": true}`? Does that return an error, or does it perform both of those actions?\r\n\r\nThis is already slightly confusing in that `POST /db/name-of-query` is the existing API for executing a writable canned query: https://docs.datasette.io/en/stable/sql_queries.html#json-api-for-writable-canned-queries\r\n\r\nSo I'm ready to consider other design options.\r\n\r\nInitial thoughts on possible designs (for the single row insert case, but could be expanded to cover other verbs):\r\n\r\n- `POST /db/table?action=insert`\r\n- `POST /db/table?nsert`\r\n- `POST /db/table/-/insert`\r\n\r\nI quite like that third one: it feels consistent with the existing `/-/actor` etc pages that Datasette serves already.\r\n\r\nThere's one slight confusion here in that it overlaps with the URL for a row with a primary key of `\"-\"` - which is currently at `/db/table/-` - but that might be OK.\r\n\r\nEspecially if I say that child pages of rows must theselves use the `/-/` pattern. So to update or delet a row you would use:\r\n\r\n- `POST /db/table/row/-/update`\r\n- `POST /db/table/row/-/delete`\r\n\r\nSo a row with primary key `-` would end up as `/db/table/row/-/-/update` - which I think is OK.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1426195437, "label": "Design URLs for the write API"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1868#issuecomment-1294004308", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1868", "id": 1294004308, "node_id": "IC_kwDOBm6k_c5NIPBU", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-10-27T20:03:08Z", "updated_at": "2022-10-27T20:03:08Z", "author_association": "OWNER", "body": "The other option here would be to lean into custom HTTP verbs like `DELETE` and `PATCH`. I'm not sold on those: they've never given me any convincing wins over just using `POST` for the many times I've encountered them in my career to date.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1426195437, "label": "Design URLs for the write API"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1868#issuecomment-1294007024", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1868", "id": 1294007024, "node_id": "IC_kwDOBm6k_c5NIPrw", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-10-27T20:05:44Z", "updated_at": "2022-10-27T20:05:52Z", "author_association": "OWNER", "body": "So given this scheme, the URL design would look like this:\r\n\r\n- `POST /db/table/-/insert` - insert a single row\r\n- `POST /db/table/-/insert-many` - insert multiple rows (might just keep that on `/-/insert` with a JSON array rather than object though)\r\n- `POST /db/table/-/drop` - drop a table\r\n- `POST /db/table/-/alter` - alter a table\r\n- `POST /db/table/-/upsert` - upsert, https://sqlite-utils.datasette.io/en/stable/python-api.html#upserting-data\r\n- `POST /db/table/-/create` - could be an endpoint for explicitly creating a table, or should that live at `/db/-/create` instead?\r\n\r\nAnd for rows (`pks` here since compound primary keys are supported):\r\n\r\n- `POST /db/table/pks/-/update` - update row\r\n- `POST /db/table/pks/-/delete` - delete row", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1426195437, "label": "Design URLs for the write API"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1868#issuecomment-1294008282", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1868", "id": 1294008282, "node_id": "IC_kwDOBm6k_c5NIP_a", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-10-27T20:06:34Z", "updated_at": "2022-10-27T20:06:34Z", "author_association": "OWNER", "body": "I'm going to stick with one `/-/insert` endpoint which handles both single row inserts AND multiple row inserts I think - partly because I don't want to build both `/-/upsert` and `/-/upsert-many`, I'd rather just have `/-/upsert`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1426195437, "label": "Design URLs for the write API"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1868#issuecomment-1294008733", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1868", "id": 1294008733, "node_id": "IC_kwDOBm6k_c5NIQGd", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-10-27T20:07:01Z", "updated_at": "2022-10-27T20:07:01Z", "author_association": "OWNER", "body": "I'm happy with this `/db/table/-/action` design for the moment. Will review it once I've built it to see if I still like it!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1426195437, "label": "Design URLs for the write API"}, "performed_via_github_app": null}