From bb917467ff8a8eebab342a3ae10667b0785fd293 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 18 Feb 2022 17:44:08 +0000 Subject: [PATCH] Adding in row schema for create/update, making sure all existing endpoints have appId specified. --- packages/server/specs/examples.js | 61 ++-- packages/server/specs/generate.js | 4 + packages/server/specs/openapi.json | 294 ++++++++++++++++-- packages/server/specs/openapi.yaml | 166 +++++++++- packages/server/specs/parameters.js | 10 + packages/server/specs/schemas.js | 13 + .../server/src/api/controllers/public/rows.js | 24 +- .../src/api/controllers/public/tables.js | 10 +- packages/server/src/api/routes/public/rows.js | 39 ++- .../server/src/api/routes/public/tables.js | 93 +++--- 10 files changed, 578 insertions(+), 136 deletions(-) create mode 100644 packages/server/specs/schemas.js diff --git a/packages/server/specs/examples.js b/packages/server/specs/examples.js index 0ae5da4025..85cd5b1fed 100644 --- a/packages/server/specs/examples.js +++ b/packages/server/specs/examples.js @@ -1,9 +1,18 @@ -const row = { +const baseRow = { _id: "ro_ta_5b1649e42a5b41dea4ef7742a36a7a70_e6dc7e38cf1343b2b56760265201cda4", type: "row", tableId: "ta_5b1649e42a5b41dea4ef7742a36a7a70", name: "Mike", age: 30, +} + +const inputRow = { + ...baseRow, + relationship: ["ro_ta_..."], +} + +const row = { + ...baseRow, relationship: [ { primaryDisplay: "Joe", @@ -12,30 +21,40 @@ const row = { ], } -exports.table = { - value: { - _id: "ta_5b1649e42a5b41dea4ef7742a36a7a70", - name: "People", - schema: { - name: { - type: "string", - name: "name", - }, - age: { - type: "number", - name: "age", - }, - relationship: { - type: "link", - name: "relationship", - tableId: "ta_...", - fieldName: "relatedColumn", - relationshipType: "many-to-many", - }, +const table = { + _id: "ta_5b1649e42a5b41dea4ef7742a36a7a70", + name: "People", + schema: { + name: { + type: "string", + name: "name", + }, + age: { + type: "number", + name: "age", + }, + relationship: { + type: "link", + name: "relationship", + tableId: "ta_...", + fieldName: "relatedColumn", + relationshipType: "many-to-many", }, }, } +exports.table = { + value: table, +} + +exports.tables = { + value: [table], +} + +exports.inputRow = { + value: inputRow, +} + exports.row = { value: row, } diff --git a/packages/server/specs/generate.js b/packages/server/specs/generate.js index 351c2b8728..b940ae6642 100644 --- a/packages/server/specs/generate.js +++ b/packages/server/specs/generate.js @@ -4,6 +4,7 @@ const { writeFileSync } = require("fs") const examples = require("./examples") const parameters = require("./parameters") const security = require("./security") +const schemas = require("./schemas") const VARIABLES = {} @@ -35,6 +36,9 @@ const options = { securitySchemes: { ...security, }, + schemas: { + ...schemas, + }, }, security: [ { diff --git a/packages/server/specs/openapi.json b/packages/server/specs/openapi.json index 2d2dd9b05d..ada160d752 100644 --- a/packages/server/specs/openapi.json +++ b/packages/server/specs/openapi.json @@ -34,6 +34,15 @@ "schema": { "type": "string" } + }, + "appId": { + "in": "header", + "name": "appId", + "required": true, + "description": "The ID of the app which this request is targeting.", + "schema": { + "type": "string" + } } }, "examples": { @@ -60,6 +69,43 @@ } } }, + "tables": { + "value": [ + { + "_id": "ta_5b1649e42a5b41dea4ef7742a36a7a70", + "name": "People", + "schema": { + "name": { + "type": "string", + "name": "name" + }, + "age": { + "type": "number", + "name": "age" + }, + "relationship": { + "type": "link", + "name": "relationship", + "tableId": "ta_...", + "fieldName": "relatedColumn", + "relationshipType": "many-to-many" + } + } + } + ] + }, + "inputRow": { + "value": { + "_id": "ro_ta_5b1649e42a5b41dea4ef7742a36a7a70_e6dc7e38cf1343b2b56760265201cda4", + "type": "row", + "tableId": "ta_5b1649e42a5b41dea4ef7742a36a7a70", + "name": "Mike", + "age": 30, + "relationship": [ + "ro_ta_..." + ] + } + }, "row": { "value": { "_id": "ro_ta_5b1649e42a5b41dea4ef7742a36a7a70_e6dc7e38cf1343b2b56760265201cda4", @@ -104,6 +150,31 @@ "name": "x-budibase-api-key", "description": "Your individual API key, this will provide access based on the configured RBAC settings of your user." } + }, + "schemas": { + "row": { + "description": "The row to be created/updated, based on the table schema.", + "type": "object", + "additionalProperties": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + }, + { + "type": "integer" + }, + { + "type": "array" + }, + { + "type": "boolean" + } + ] + } + } } }, "security": [ @@ -121,6 +192,9 @@ "parameters": [ { "$ref": "#/components/parameters/tableId" + }, + { + "$ref": "#/components/parameters/appId" } ], "requestBody": { @@ -151,7 +225,13 @@ }, "range": { "type": "object", - "description": "Searches within a range, the format of this must be columnName -> [low, high]." + "description": "Searches within a range, the format of this must be columnName -> [low, high].", + "example": { + "columnName1": [ + 10, + 20 + ] + } }, "equal": { "type": "object", @@ -163,7 +243,10 @@ }, "empty": { "type": "object", - "description": "Searches for rows which do not contain the specified column. The object should simply contain keys of the column names, these can map to any value." + "description": "Searches for rows which do not contain the specified column. The object should simply contain keys of the column names, these can map to any value.", + "example": { + "columnName1": "" + } }, "notEmpty": { "type": "object", @@ -255,11 +338,11 @@ "description": "If pagination in use, this will determine if there is another page to fetch.", "type": "boolean" } - }, - "examples": { - "search": [ - "#/components/examples/search" - ] + } + }, + "examples": { + "search": { + "$ref": "#/components/examples/search" } } } @@ -277,6 +360,9 @@ "parameters": [ { "$ref": "#/components/parameters/tableId" + }, + { + "$ref": "#/components/parameters/appId" } ], "requestBody": { @@ -284,29 +370,11 @@ "content": { "application/json": { "schema": { - "description": "The contents of the row which is to be created, the keys of", - "type": "object", - "example": { - "$ref": "#/components/examples/row" - }, - "additionalProperties": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "object" - }, - { - "type": "integer" - }, - { - "type": "array" - }, - { - "type": "boolean" - } - ] + "$ref": "#/components/schemas/row" + }, + "examples": { + "row": { + "$ref": "#/components/examples/inputRow" } } } @@ -343,8 +411,26 @@ }, { "$ref": "#/components/parameters/rowId" + }, + { + "$ref": "#/components/parameters/appId" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/row" + }, + "examples": { + "row": { + "$ref": "#/components/examples/inputRow" + } + } + } + } + }, "responses": { "200": { "description": "Returns the created row, including the ID which has been generated for it.", @@ -374,6 +460,9 @@ }, { "$ref": "#/components/parameters/rowId" + }, + { + "$ref": "#/components/parameters/appId" } ], "responses": { @@ -405,6 +494,9 @@ }, { "$ref": "#/components/parameters/rowId" + }, + { + "$ref": "#/components/parameters/appId" } ], "responses": { @@ -426,22 +518,158 @@ } } }, + "/tables/search": { + "post": { + "summary": "Search internal and external tables based on their name.", + "parameters": [ + { + "$ref": "#/components/parameters/appId" + } + ], + "tags": [ + "tables" + ], + "requestBody": null, + "responses": { + "200": { + "description": "Returns the found tables, based on the search parameters.", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "object" + } + }, + "examples": { + "tables": { + "$ref": "#/components/examples/tables" + } + } + } + } + } + } + } + }, "/tables": { "post": { - "summary": "Create a new table", + "summary": "Create a new table.", + "parameters": [ + { + "$ref": "#/components/parameters/appId" + } + ], "tags": [ "tables" ], "responses": { "200": { - "description": "Returns the created table, including the ID which has been generated for it.", + "description": "Returns the created table, including the ID which has been generated for it. This can be internal or external data sources.", "content": { "application/json": { "schema": { "type": "object" }, "examples": { - "row": { + "table": { + "$ref": "#/components/examples/table" + } + } + } + } + } + } + }, + "get": { + "summary": "Get all the tables, internal and external within an app.", + "tags": [ + "tables" + ], + "parameters": [ + { + "$ref": "#/components/parameters/tableId" + }, + { + "$ref": "#/components/parameters/appId" + } + ], + "responses": { + "200": { + "description": "Returns all of the tables which were found.", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "examples": { + "table": { + "$ref": "#/components/examples/row" + } + } + } + } + } + } + } + }, + "/tables/:tableId": { + "put": { + "summary": "Update the specified table. This can be for internal or external tables.", + "tags": [ + "tables" + ], + "parameters": [ + { + "$ref": "#/components/parameters/tableId" + }, + { + "$ref": "#/components/parameters/appId" + } + ], + "responses": { + "200": { + "description": "Returns the updated table.", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "examples": { + "table": { + "$ref": "#/components/examples/row" + } + } + } + } + } + } + } + }, + "/tables/{tableId}": { + "delete": { + "summary": "Delete a single table and all of its data.", + "tags": [ + "tables" + ], + "parameters": [ + { + "$ref": "#/components/parameters/tableId" + }, + { + "$ref": "#/components/parameters/appId" + } + ], + "responses": { + "200": { + "description": "Returns the deleted table.", + "content": { + "application/json": { + "schema": { + "type": "object" + }, + "examples": { + "table": { "$ref": "#/components/examples/table" } } diff --git a/packages/server/specs/openapi.yaml b/packages/server/specs/openapi.yaml index eeb729a1e4..18a5d13e78 100644 --- a/packages/server/specs/openapi.yaml +++ b/packages/server/specs/openapi.yaml @@ -24,6 +24,13 @@ components: description: The ID of the row which this request is targeting. schema: type: string + appId: + in: header + name: appId + required: true + description: The ID of the app which this request is targeting. + schema: + type: string examples: table: value: @@ -42,6 +49,32 @@ components: tableId: ta_... fieldName: relatedColumn relationshipType: many-to-many + tables: + value: + - _id: ta_5b1649e42a5b41dea4ef7742a36a7a70 + name: People + schema: + name: + type: string + name: name + age: + type: number + name: age + relationship: + type: link + name: relationship + tableId: ta_... + fieldName: relatedColumn + relationshipType: many-to-many + inputRow: + value: + _id: ro_ta_5b1649e42a5b41dea4ef7742a36a7a70_e6dc7e38cf1343b2b56760265201cda4 + type: row + tableId: ta_5b1649e42a5b41dea4ef7742a36a7a70 + name: Mike + age: 30 + relationship: + - ro_ta_... row: value: _id: ro_ta_5b1649e42a5b41dea4ef7742a36a7a70_e6dc7e38cf1343b2b56760265201cda4 @@ -72,6 +105,17 @@ components: name: x-budibase-api-key description: Your individual API key, this will provide access based on the configured RBAC settings of your user. + schemas: + row: + description: The row to be created/updated, based on the table schema. + type: object + additionalProperties: + oneOf: + - type: string + - type: object + - type: integer + - type: array + - type: boolean security: - ApiKeyAuth: [] paths: @@ -82,6 +126,7 @@ paths: - rows parameters: - $ref: "#/components/parameters/tableId" + - $ref: "#/components/parameters/appId" requestBody: required: true content: @@ -109,6 +154,10 @@ paths: type: object description: Searches within a range, the format of this must be columnName -> [low, high]. + example: + columnName1: + - 10 + - 20 equal: type: object description: Searches for rows that have a column value that is exactly the @@ -122,6 +171,8 @@ paths: description: Searches for rows which do not contain the specified column. The object should simply contain keys of the column names, these can map to any value. + example: + columnName1: "" notEmpty: type: object description: Searches for rows which have the specified column. @@ -188,9 +239,9 @@ paths: description: If pagination in use, this will determine if there is another page to fetch. type: boolean - examples: - search: - - "#/components/examples/search" + examples: + search: + $ref: "#/components/examples/search" "/tables/{tableId}/rows": post: summary: Creates a new row within a specified table. @@ -198,22 +249,16 @@ paths: - rows parameters: - $ref: "#/components/parameters/tableId" + - $ref: "#/components/parameters/appId" requestBody: required: true content: application/json: schema: - description: The contents of the row which is to be created, the keys of - type: object - example: - $ref: "#/components/examples/row" - additionalProperties: - oneOf: - - type: string - - type: object - - type: integer - - type: array - - type: boolean + $ref: "#/components/schemas/row" + examples: + row: + $ref: "#/components/examples/inputRow" responses: "200": description: Returns the created row, including the ID which has been generated @@ -234,6 +279,16 @@ paths: parameters: - $ref: "#/components/parameters/tableId" - $ref: "#/components/parameters/rowId" + - $ref: "#/components/parameters/appId" + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/row" + examples: + row: + $ref: "#/components/examples/inputRow" responses: "200": description: Returns the created row, including the ID which has been generated @@ -252,6 +307,7 @@ paths: parameters: - $ref: "#/components/parameters/tableId" - $ref: "#/components/parameters/rowId" + - $ref: "#/components/parameters/appId" responses: "200": description: Returns the deleted row, including the ID which has been generated @@ -270,6 +326,7 @@ paths: parameters: - $ref: "#/components/parameters/tableId" - $ref: "#/components/parameters/rowId" + - $ref: "#/components/parameters/appId" responses: "200": description: Returns the retrieved row. @@ -280,20 +337,95 @@ paths: examples: row: $ref: "#/components/examples/row" + /tables/search: + post: + summary: Search internal and external tables based on their name. + parameters: + - $ref: "#/components/parameters/appId" + tags: + - tables + requestBody: null + responses: + "200": + description: Returns the found tables, based on the search parameters. + content: + application/json: + schema: + type: array + items: + type: object + examples: + tables: + $ref: "#/components/examples/tables" /tables: post: - summary: Create a new table + summary: Create a new table. + parameters: + - $ref: "#/components/parameters/appId" tags: - tables responses: "200": description: Returns the created table, including the ID which has been - generated for it. + generated for it. This can be internal or external data sources. content: application/json: schema: type: object examples: - row: + table: + $ref: "#/components/examples/table" + get: + summary: Get all the tables, internal and external within an app. + tags: + - tables + parameters: + - $ref: "#/components/parameters/tableId" + - $ref: "#/components/parameters/appId" + responses: + "200": + description: Returns all of the tables which were found. + content: + application/json: + schema: + type: object + examples: + table: + $ref: "#/components/examples/row" + /tables/:tableId: + put: + summary: Update the specified table. This can be for internal or external tables. + tags: + - tables + parameters: + - $ref: "#/components/parameters/tableId" + - $ref: "#/components/parameters/appId" + responses: + "200": + description: Returns the updated table. + content: + application/json: + schema: + type: object + examples: + table: + $ref: "#/components/examples/row" + "/tables/{tableId}": + delete: + summary: Delete a single table and all of its data. + tags: + - tables + parameters: + - $ref: "#/components/parameters/tableId" + - $ref: "#/components/parameters/appId" + responses: + "200": + description: Returns the deleted table. + content: + application/json: + schema: + type: object + examples: + table: $ref: "#/components/examples/table" tags: [] diff --git a/packages/server/specs/parameters.js b/packages/server/specs/parameters.js index ce5874c3f1..0adad6953f 100644 --- a/packages/server/specs/parameters.js +++ b/packages/server/specs/parameters.js @@ -17,3 +17,13 @@ exports.rowId = { type: "string", }, } + +exports.appId = { + in: "header", + name: "appId", + required: true, + description: "The ID of the app which this request is targeting.", + schema: { + type: "string", + }, +} diff --git a/packages/server/specs/schemas.js b/packages/server/specs/schemas.js new file mode 100644 index 0000000000..29a6b5b84f --- /dev/null +++ b/packages/server/specs/schemas.js @@ -0,0 +1,13 @@ +exports.row = { + description: "The row to be created/updated, based on the table schema.", + type: "object", + additionalProperties: { + oneOf: [ + { type: "string" }, + { type: "object" }, + { type: "integer" }, + { type: "array" }, + { type: "boolean" }, + ], + }, +} diff --git a/packages/server/src/api/controllers/public/rows.js b/packages/server/src/api/controllers/public/rows.js index 7c2fad4102..2b14230fc4 100644 --- a/packages/server/src/api/controllers/public/rows.js +++ b/packages/server/src/api/controllers/public/rows.js @@ -1,17 +1,35 @@ +// makes sure that the user doesn't need to pass in the type, tableId or _id params for +// the call to be correct +function fixRow(row, params) { + if (!params || !row) { + return row + } + if (params.rowId) { + row._id = params.rowId + } + if (params.tableId) { + row.tableId = params.tableId + } + if (!row.type) { + row.type = "row" + } + return row +} + exports.search = () => { } exports.create = () => { - + ctx.request.body = fixRow(ctx.request.body, ctx.params) } exports.singleRead = () => { } -exports.update = () => { - +exports.update = async ctx => { + ctx.request.body = fixRow(ctx.request.body, ctx.params) } exports.delete = () => { diff --git a/packages/server/src/api/controllers/public/tables.js b/packages/server/src/api/controllers/public/tables.js index 68302f1120..7c2fad4102 100644 --- a/packages/server/src/api/controllers/public/tables.js +++ b/packages/server/src/api/controllers/public/tables.js @@ -1,12 +1,12 @@ +exports.search = () => { + +} + exports.create = () => { } -exports.getAllTables = () => { - -} - -exports.getSingleTable = () => { +exports.singleRead = () => { } diff --git a/packages/server/src/api/routes/public/rows.js b/packages/server/src/api/routes/public/rows.js index 2e86e53aec..393f030241 100644 --- a/packages/server/src/api/routes/public/rows.js +++ b/packages/server/src/api/routes/public/rows.js @@ -12,6 +12,7 @@ const router = Router() * - rows * parameters: * - $ref: '#/components/parameters/tableId' + * - $ref: '#/components/parameters/appId' * requestBody: * required: true * content: @@ -40,6 +41,8 @@ const router = Router() * type: object * description: Searches within a range, the format of this must be * columnName -> [low, high]. + * example: + * columnName1: [10, 20] * equal: * type: object * description: Searches for rows that have a column value that is @@ -53,6 +56,8 @@ const router = Router() * description: Searches for rows which do not contain the specified column. * The object should simply contain keys of the column names, these * can map to any value. + * example: + * columnName1: "" * notEmpty: * type: object * description: Searches for rows which have the specified column. @@ -110,9 +115,9 @@ const router = Router() * hasNextPage: * description: If pagination in use, this will determine if there is another page to fetch. * type: boolean - * examples: - * search: - * - '#/components/examples/search' + * examples: + * search: + * $ref: '#/components/examples/search' */ router.post("/tables/:tableId/rows/search", controller.search) @@ -125,22 +130,16 @@ router.post("/tables/:tableId/rows/search", controller.search) * - rows * parameters: * - $ref: '#/components/parameters/tableId' + * - $ref: '#/components/parameters/appId' * requestBody: * required: true * content: * application/json: * schema: - * description: The contents of the row which is to be created, the keys of - * type: object - * example: - * $ref: '#/components/examples/row' - * additionalProperties: - * oneOf: - * - type: string - * - type: object - * - type: integer - * - type: array - * - type: boolean + * $ref: '#/components/schemas/row' + * examples: + * row: + * $ref: '#/components/examples/inputRow' * responses: * 200: * description: Returns the created row, including the ID which has been generated for it. @@ -165,6 +164,16 @@ router.post("/tables/:tableId/rows", controller.create) * parameters: * - $ref: '#/components/parameters/tableId' * - $ref: '#/components/parameters/rowId' + * - $ref: '#/components/parameters/appId' + * requestBody: + * required: true + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/row' + * examples: + * row: + * $ref: '#/components/examples/inputRow' * responses: * 200: * description: Returns the created row, including the ID which has been generated for it. @@ -188,6 +197,7 @@ router.put("/tables/:tableId/rows/:rowId", controller.update) * parameters: * - $ref: '#/components/parameters/tableId' * - $ref: '#/components/parameters/rowId' + * - $ref: '#/components/parameters/appId' * responses: * 200: * description: Returns the deleted row, including the ID which has been generated for it. @@ -211,6 +221,7 @@ router.delete("/tables/:tableId/rows/:rowId", controller.delete) * parameters: * - $ref: '#/components/parameters/tableId' * - $ref: '#/components/parameters/rowId' + * - $ref: '#/components/parameters/appId' * responses: * 200: * description: Returns the retrieved row. diff --git a/packages/server/src/api/routes/public/tables.js b/packages/server/src/api/routes/public/tables.js index abc5734710..91690389de 100644 --- a/packages/server/src/api/routes/public/tables.js +++ b/packages/server/src/api/routes/public/tables.js @@ -2,22 +2,52 @@ const Router = require("@koa/router") const controller = require("../../controllers/public/tables") const router = Router() + +/** + * @openapi + * /tables/search: + * post: + * summary: Search internal and external tables based on their name. + * parameters: + * - $ref: '#/components/parameters/appId' + * tags: + * - tables + * requestBody: + * + * responses: + * 200: + * description: Returns the found tables, based on the search parameters. + * content: + * application/json: + * schema: + * type: array + * items: + * type: object + * examples: + * tables: + * $ref: '#/components/examples/tables' + */ +router.post("/tables/search", controller.search) + /** * @openapi * /tables: * post: - * summary: Create a new table + * summary: Create a new table. + * parameters: + * - $ref: '#/components/parameters/appId' * tags: * - tables * responses: * 200: - * description: Returns the created table, including the ID which has been generated for it. + * description: Returns the created table, including the ID which has been generated for it. This can be + * internal or external data sources. * content: * application/json: * schema: * type: object * examples: - * row: + * table: * $ref: '#/components/examples/table' */ router.post("/tables", controller.create) @@ -26,21 +56,21 @@ router.post("/tables", controller.create) * @openapi * /tables/:tableId: * put: - * summary: Update a single row within a specified table. + * summary: Update the specified table. This can be for internal or external tables. * tags: * - tables * parameters: * - $ref: '#/components/parameters/tableId' - * - $ref: '#/components/parameters/rowId' + * - $ref: '#/components/parameters/appId' * responses: * 200: - * description: Returns the created row, including the ID which has been generated for it. + * description: Returns the updated table. * content: * application/json: * schema: * type: object * examples: - * row: + * table: * $ref: '#/components/examples/row' */ router.put("/tables/:tableId", controller.update) @@ -49,68 +79,45 @@ router.put("/tables/:tableId", controller.update) * @openapi * /tables: * get: - * summary: Update a single row within a specified table. + * summary: Get all the tables, internal and external within an app. * tags: * - tables * parameters: * - $ref: '#/components/parameters/tableId' - * - $ref: '#/components/parameters/rowId' + * - $ref: '#/components/parameters/appId' * responses: * 200: - * description: Returns the created row, including the ID which has been generated for it. + * description: Returns all of the tables which were found. * content: * application/json: * schema: * type: object * examples: - * row: + * table: * $ref: '#/components/examples/row' */ -router.get("/tables", controller.getAllTables) +router.get("/tables", controller.singleRead) /** * @openapi - * /tables/{tableId}/rows/{rowId}: - * put: - * summary: Update a single row within a specified table. + * /tables/{tableId}: + * delete: + * summary: Delete a single table and all of its data. * tags: - * - rows + * - tables * parameters: * - $ref: '#/components/parameters/tableId' - * - $ref: '#/components/parameters/rowId' + * - $ref: '#/components/parameters/appId' * responses: * 200: - * description: Returns the created row, including the ID which has been generated for it. + * description: Returns the deleted table. * content: * application/json: * schema: * type: object * examples: - * row: - * $ref: '#/components/examples/row' - */ -router.get("/tables/:tableId", controller.getSingleTable) - -/** - * @openapi - * /tables/{tableId}/rows/{rowId}: - * put: - * summary: Update a single row within a specified table. - * tags: - * - rows - * parameters: - * - $ref: '#/components/parameters/tableId' - * - $ref: '#/components/parameters/rowId' - * responses: - * 200: - * description: Returns the created row, including the ID which has been generated for it. - * content: - * application/json: - * schema: - * type: object - * examples: - * row: - * $ref: '#/components/examples/row' + * table: + * $ref: '#/components/examples/table' */ router.delete("/tables/:tableId", controller.delete)