diff --git a/api-reference/v2/resources/changelog.mdx b/api-reference/v2/resources/changelog.mdx index d16decc..a12ad41 100644 --- a/api-reference/v2/resources/changelog.mdx +++ b/api-reference/v2/resources/changelog.mdx @@ -3,6 +3,12 @@ title: Glide API Changelog sidebarTitle: Changelog --- +### November 21, 2024 + +- Introduced `HEAD /tables/{tableID}/rows` endpoint to retrieve the current version of table data via `ETag` header. +- Added support for the `If-Match` header to the Overwrite Table and Update Row endpoints. +- Introduced a new Data Versioning guide. + ### November 11, 2024 - Added `GET /tables/{tableID}/rows` endpoint to retrieve rows from a specified table with pagination. diff --git a/api-reference/v2/tables/get-table-rows.mdx b/api-reference/v2/tables/get-table-rows.mdx index 9fed2f1..88ed395 100644 --- a/api-reference/v2/tables/get-table-rows.mdx +++ b/api-reference/v2/tables/get-table-rows.mdx @@ -2,3 +2,7 @@ title: Get Rows openapi: get /tables/{tableID}/rows --- + +You can use the `limit` query parameter to specify the maximum number of rows to return for each request. + +Whether or not you supply a `limit`, you may need to make multiple requests to retrieve all the rows in the table. If there are more rows to fetch, the `continuation` field will be set in the response. To retrieve the next page of rows, make another request with the `continuation` as a query parameter. \ No newline at end of file diff --git a/api-reference/v2/tables/head-table-rows.mdx b/api-reference/v2/tables/head-table-rows.mdx new file mode 100644 index 0000000..46bc11b --- /dev/null +++ b/api-reference/v2/tables/head-table-rows.mdx @@ -0,0 +1,20 @@ +--- +title: Get Rows Version +openapi: head /tables/{tableID}/rows +--- + +Returns an `ETag` header containing the current version of the table data. + +This endpoint may be polled to detect changes in the table's data. + + + To learn more about versioning and how to detect changes, please see our guide on [data versioning](/api-reference/v2/tables/versioning). + + +--- + +#### Response Headers + + +The current version of the table data. + \ No newline at end of file diff --git a/api-reference/v2/tables/put-tables.mdx b/api-reference/v2/tables/put-tables.mdx index eaf42a7..682047a 100644 --- a/api-reference/v2/tables/put-tables.mdx +++ b/api-reference/v2/tables/put-tables.mdx @@ -3,18 +3,27 @@ title: Overwrite Table openapi: put /tables/{tableID} --- -Overwrite an existing Big Table by clearing all rows and adding new data. You can also update the table schema. +Overwrite an existing Big Table by clearing all rows and adding new data. -When using a CSV or TSV request body, you cannot pass a schema. The current schema will be used. If you need to update the schema, use the `onSchemaError=updateSchema` query parameter, or [stash](/api-reference/v2/stashing/introduction) the CSV/TSV data and pass a JSON request body. +### Updating the Schema - -This is a destructive operation that cannot be undone. - +You can optionally update the table schema at the same time by providing a new schema in the JSON request body. If you do not provide a schema, the existing schema will be used. + +When using a CSV or TSV request body, you cannot pass a schema. If you need to update the schema, use the `onSchemaError=updateSchema` query parameter, or [stash](/api-reference/v2/stashing/introduction) the CSV/TSV data and pass a JSON request body referencing the stash ID. ## Examples - + + To clear all rows from a table, send a PUT request with an empty array in the `rows` field: + + ```json + { + "rows": [] + } + ``` + + If you want to reset a table's data with a small number of rows, you can do so by providing the data inline in the `rows` field (being sure that row object structure matches the table schema): ```json @@ -30,15 +39,34 @@ This is a destructive operation that cannot be undone. However, this is only appropriate for relatively small initial datasets (around a few hundred rows or less, depending on schema complexity). If you need to work with a larger dataset you should utilize stashing. - + [Stashing](/api-reference/v2/stashing/introduction) is our process for handling the upload of large datasets. Break down your dataset into smaller, more manageable, pieces and [upload them to a single stash ID](/api-reference/v2/stashing/post-stashes-serial). Then, to reset a table's data from the stash, use the `$stashID` reference in the `rows` field instead of providing the data inline: ```json { - "$stashID": "20240215-job32" + "rows": { "$stashID": "20240215-job32" } } ``` + + This endpoint can be combined with the [Get Rows](/api-reference/v2/tables/get-table-rows) endpoint and [stashing](/api-reference/v2/stashing/introduction) to fetch the current table data, modify it, and then overwrite the table with the updated data: + + 1. Call the [Get Rows](/api-reference/v2/tables/get-table-rows) endpoint to fetch the current table data. Pass a reasonably high `limit` query parameter because you want to fetch all rows in as few requests as possible. + 2. Modify the data as desired, and then stash the modified rows using the [Stash Data](/api-reference/v2/stashing/put-stashes-serial) endpoint. + 3. If a `continuation` was returned in step 1, repeat steps 1-3, passing the `continuation` query parameter to [Get Rows](/api-reference/v2/tables/get-table-rows) until all rows have been fetched, modified, and stashed. + 4. Finally, call this endpoint with same stash ID used in step 2. This will overwrite the table with the updated data: + + ```json + { + "rows": { "$stashID": "20240215-job32" } + } + ``` + + **Risk of Data Loss** + + We strongly recommend you use the `If-Match` header to ensure the table is not modified between steps 1 and 4. See the [Data Versioning](/api-reference/v2/tables/versioning) guide for more information. + + \ No newline at end of file diff --git a/api-reference/v2/tables/versioning.mdx b/api-reference/v2/tables/versioning.mdx new file mode 100644 index 0000000..1aee173 --- /dev/null +++ b/api-reference/v2/tables/versioning.mdx @@ -0,0 +1,21 @@ +--- +title: Data Versioning +description: Detect updates and prevent data loss with versioning +--- + +Every Glide Big Table has a version number that increases whenever its data changes. Additionally, each row in a Big Table keeps track of the table version when it was last modified. This information can be used to detect changes to data and prevent mid-air collisions that can result in data loss. + +## Getting the Current Version + +Most API endpoints that work with Big Tables return the current version of the table in the `ETag` response header. + +If you only want to get the current version of a table without performing any other operation, use the [Get Rows Version](/api-reference/v2/tables/head-table-rows) endpoint. You can poll this endpoint to detect changes to the table. + +## Preventing Data Loss + +When updating data in a Big Table, you can specify the version of the table you expect to be working with using the `If-Match` header. How this value is interpreted depends on the endpoint: + +- The [Overwrite Table](/api-reference/v2/tables/put-tables) endpoint rejects the request if the current table version is newer than the version specified in the `If-Match` header. +- The [Update Row](/api-reference/v2/tables/patch-table-row) endpoint rejects the request if the row has been modified since the version specified in the `If-Match` header. The update is still allowed if another row in the table was modified since the specified version. + +In both cases, an HTTP `412 Precondition Failed` response is returned if the condition is not met. \ No newline at end of file diff --git a/mint.json b/mint.json index cc7ad21..179cb4d 100644 --- a/mint.json +++ b/mint.json @@ -34,8 +34,10 @@ { "group": "Tables", "pages": [ + "api-reference/v2/tables/versioning", "api-reference/v2/tables/get-tables", "api-reference/v2/tables/get-table-rows", + "api-reference/v2/tables/head-table-rows", "api-reference/v2/tables/post-tables", "api-reference/v2/tables/post-table-rows", "api-reference/v2/tables/put-tables", diff --git a/openapi/swagger.json b/openapi/swagger.json index cd6706f..fb4fcc2 100644 --- a/openapi/swagger.json +++ b/openapi/swagger.json @@ -649,6 +649,16 @@ } }, "parameters": [ + { + "name": "if-match", + "in": "header", + "schema": { + "type": "string", + "pattern": "^\"[0-9]+\"$", + "description": "ETag of the current table version. If provided, the request will fail if the table has been updated since this version." + }, + "required": false + }, { "name": "tableID", "in": "path", @@ -896,6 +906,103 @@ } }, "/tables/{tableID}/rows": { + "head": { + "responses": { + "200": { + "description": "", + "headers": { + "ETag": { + "schema": { + "type": "string", + "description": "The current version of the table" + }, + "required": true + } + } + }, + "400": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "additionalProperties": false + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } + } + }, + "404": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "table_not_found", + "table_not_big_table" + ] + }, + "message": { + "type": "string" + } + }, + "required": [ + "type", + "message" + ], + "additionalProperties": false + } + }, + "required": [ + "error" + ], + "additionalProperties": false + } + } + } + } + }, + "parameters": [ + { + "name": "tableID", + "in": "path", + "schema": { + "type": "string", + "description": "ID of the table, e.g., `2a1bad8b-cf7c-44437-b8c1-e3782df6`", + "example": "2a1bad8b-cf7c-44437-b8c1-e3782df6" + }, + "required": true + } + ], + "description": "Gets information about the data in a Big Table" + }, "get": { "responses": { "200": { @@ -996,7 +1103,6 @@ "in": "query", "schema": { "type": "number", - "default": 250, "description": "Maximum number of rows to return in a single response. No more than this number of rows will be returned, however fewer rows may be returned, even if there are more rows to fetch. If there are more rows, the response will include a continuation token that can be used to fetch the next set of rows." }, "required": false @@ -1382,6 +1488,16 @@ } }, "parameters": [ + { + "name": "if-match", + "in": "header", + "schema": { + "type": "string", + "pattern": "^\"[0-9]+\"$", + "description": "ETag of the current table version. If provided, the request will fail if the table has been updated since this version." + }, + "required": false + }, { "name": "tableID", "in": "path",