tiptap/docs/collaboration/backend-document-manipulation.md
2024-02-20 09:02:34 +01:00

182 lines
6.0 KiB
Markdown

# Backend Document Manipulation
Backend Document Manipulation allows developers to programmatically modify documents stored on the Collaboration server (On premises and Cloud).
This feature provides flexibility in document management, enabling updates through JSON, which is a simpler alternative to using Yjs methods directly.
The feature is fully compliant with Version history, and allows to track changes from users, as well as the Backend Document Manipulation feature.
:::warning Pro Extension
This feature requires a valid Business or Enterprise subscription and a running [Tiptap Cloud instance](https://collab.tiptap.dev/).
:::
### Use Cases
Backend Document Manipulation enables a variety of use cases, such as:
- Live translation of document content.
- Server-side components, like executing an SQL query and displaying results.
- Automatic typo and grammar corrections.
- Version history integration and conflict-free merging of concurrent edits.
This powerful feature set allows for extensive customization and automation of document handling on the Tiptap platform, catering to a wide range of collaborative editing scenarios.
## Update Document
To update an existing document on the Collaboration server, you can use the `PATCH` method with the following API endpoint:
```bash
PATCH /api/documents/:identifier?format=:format
```
This endpoint accepts a Yjs update message and applies it to the specified document. The `format` query parameter specifies the format of the update and can be one of the following:
- `binary`: Directly using Yjs's `Y.encodeStateAsUpdate` method.
- `base64`: The binary state encoded as a Base64 string.
- `json`: Updates the document using JSON format (with some caveats, see below).
Upon successful update, the server will return HTTP status `204`. If the document does not exist, it will return `404`, and if the payload is invalid or the update cannot be applied, it will return `422`.
Example `curl` command to update a document:
```bash
curl --location --request PATCH 'https://YOUR_APP_ID.collab.tiptap.cloud/api/documents/DOCUMENT_NAME' \\
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA' \\
--data '@yjsUpdate.binary.txt'
```
### Update via JSON
When updating via JSON, the server computes the difference between the current document state and the provided JSON, then internally calculates the required Yjs update to reach the target state.
To ensure precise updates, especially for node-specific changes, it is recommended to use the `nodeAttributeName` and `nodeAttributeValue` parameters. These can be generated by Tiptap's [UniqueID Extension](https://tiptap.dev/docs/editor/api/extensions/unique-id) or a custom implementation.
- `nodeAttributeName`: Configured as `attributeName` in the UniqueID extension.
- `nodeAttributeValue`: The unique value generated for the node to be updated.
From version 3.3.0 onwards, you can use `?mode=append` to append nodes to the document's JSON representation without altering existing content.
Omitting these parameters may result in overwriting any updates made between fetching the document and issuing the update call.
Here is an example of how to update a document using JSON:
```typescript
// Define the document name, secret, and application ID
const docName = ''
const secret = ''
const appId = '';
// Construct the base URL
const url = `https://${appId}.collab.tiptap.dev`
// Fetch the current document's JSON representation
const docJson = await axios.get(`${url}/api/documents/${docName}?format=json`, {
headers: {
Authorization: secret
},
})
// Extract the document's JSON content
const tiptapJson = docJson.data
const nodes = tiptapJson.content
// Find and log specific nodes using their unique identifiers
const query = nodes.find(n => n.attrs?.identifier === 'fe5c0789-85d9-4877-a2c3-bccf5d874866').content[0].text
const resultTable = nodes.find(n => n.attrs?.identifier === '246368b6-0746-4ca1-a16f-8d964aff4041')
console.log(`Query: ${query}`)
console.log(JSON.stringify(resultTable.content))
// Append new content to the result table node
resultTable.content.push({
// New table row content here
{
"type": "tableRow",
"content": [
{
"type": "tableCell",
"attrs": {
"colspan": 1,
"rowspan": 1
},
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "left"
},
"content": [
{
"type": "text",
"text": "Jan"
}
]
}
]
},
{
"type": "tableCell",
"attrs": {
"colspan": 1,
"rowspan": 1
},
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "left"
},
"content": [
{
"type": "text",
"text": "Thurau"
}
]
}
]
},
{
"type": "tableCell",
"attrs": {
"colspan": 1,
"rowspan": 1
},
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "left"
},
"content": [
{
"type": "text",
"text": "jan@janthurau.de"
}
]
}
]
}
]
}
})
// Send the updated JSON back to the server to apply the changes
await axios.patch(`${url}/api/documents/${docName}?format=json`, tiptapJson, {
headers: {
Authorization: secret
}
})
```
## Create Document
To seed a new document on the Tiptap Collab server, use the `POST` method with the following endpoint:
```bash
POST /api/documents/:identifier?format=:format
```
The server will return HTTP status `204` for successful creation, `409` if the document already exists (you must delete it first to overwrite), and `422` if the action failed.
The `format` parameter accepts the same values as the update endpoint (`binary`, `base64`, or `json`).