You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Updating system state by writing and deleting relationship tuples
5
+
description: Introduction to adding and deleting relationship tuples
6
6
---
7
7
8
8
import {
@@ -24,7 +24,7 @@ import TabItem from '@theme/TabItem';
24
24
25
25
<DocumentationNotice />
26
26
27
-
This section will illustrate how to update_<ProductConceptsection="what-is-a-relationship-tuple"linkName="relationship tuples" />_.
27
+
This is an introduction to adding and deleting_<ProductConceptsection="what-is-a-relationship-tuple"linkName="relationship tuples" />_.
28
28
29
29
## Before you start
30
30
@@ -93,7 +93,7 @@ Assume that you want to add user `user:anne` to have relationship `reader` with
93
93
{
94
94
user: 'user:anne',
95
95
relation: 'reader',
96
-
object: 'document:Z',
96
+
object: 'document:Z'
97
97
}
98
98
```
99
99
@@ -150,7 +150,7 @@ To add the relationship tuples, we can invoke the write API.
150
150
{
151
151
user: 'user:anne',
152
152
relation: 'reader',
153
-
object: 'document:Z',
153
+
object: 'document:Z'
154
154
},
155
155
]}
156
156
skipSetup={true}
@@ -175,7 +175,7 @@ Assume that you want to delete user `user:anne`'s `reader` relationship with obj
175
175
{
176
176
user: 'user:anne',
177
177
relation: 'reader',
178
-
object: 'document:Z',
178
+
object: 'document:Z'
179
179
}
180
180
```
181
181
@@ -184,7 +184,7 @@ Assume that you want to delete user `user:anne`'s `reader` relationship with obj
184
184
{
185
185
user: 'user:anne',
186
186
relation: 'reader',
187
-
object: 'document:Z',
187
+
object: 'document:Z'
188
188
},
189
189
]}
190
190
skipSetup={true}
@@ -199,11 +199,113 @@ Assume that you want to delete user `user:anne`'s `reader` relationship with obj
199
199
]}
200
200
/>
201
201
202
+
### 04. Writing and deleting relationship tuples in the same request
203
+
204
+
You can combine both writes and deletes in a single transactional API request. This is useful when you need to update multiple relationships atomically. All operations in the request will either succeed together or fail together.
205
+
206
+
The Write API allows you to send up to `100` unique tuples in the request. (This limit applies to the sum of both writes and deletes in that request).
207
+
208
+
For example, you might want to remove `user:anne` as a `writer` of `document:Z` while simultaneously updating `user:anne` as an `reader` of `document:Z`:
209
+
210
+
<WriteRequestViewer
211
+
relationshipTuples={[
212
+
{
213
+
user: 'user:anne',
214
+
relation: 'reader',
215
+
object: 'document:Z'
216
+
},
217
+
]}
218
+
deleteRelationshipTuples={[
219
+
{
220
+
user: 'user:anne',
221
+
relation: 'writer',
222
+
object: 'document:Z'
223
+
},
224
+
]}
225
+
skipSetup={true}
226
+
allowedLanguages={[
227
+
SupportedLanguage.JS_SDK,
228
+
SupportedLanguage.GO_SDK,
229
+
SupportedLanguage.DOTNET_SDK,
230
+
SupportedLanguage.PYTHON_SDK,
231
+
SupportedLanguage.JAVA_SDK,
232
+
SupportedLanguage.CLI,
233
+
SupportedLanguage.CURL,
234
+
]}
235
+
/>
236
+
237
+
This approach ensures that both operations succeed or fail together, maintaining transactional data consistency.
238
+
239
+
240
+
:::note
241
+
When using the Write API, you cannot include the same tuple (same user, relation, and object) in the writes or deletes arrays within a single request. The API will return an error with code `cannot_allow_duplicate_tuples_in_one_request` if detected.
242
+
:::
243
+
244
+
### 05. Ignoring duplicate or missing tuples
245
+
246
+
Sometimes you might need to write a tuple that already exists, which would normally cause the whole request to fail. You can use the `on_duplicate: "ignore"` parameter to handle this gracefully.
247
+
248
+
This is particularly useful for high-volume data imports, migrations, or ensuring certain permissions exist without complex error handling logic.
249
+
250
+
For example, if you want to ensure `user:anne` has `reader` access to `document:Z` without worrying about whether the relationship already exists in <ProductNameformat={ProductNameFormat.ShortForm}/>:
251
+
252
+
<WriteRequestViewer
253
+
relationshipTuples={[
254
+
{
255
+
user: 'user:anne',
256
+
relation: 'reader',
257
+
object: 'document:Z'
258
+
},
259
+
]}
260
+
writeOptions={{
261
+
on_duplicate: 'ignore',
262
+
}}
263
+
skipSetup={true}
264
+
allowedLanguages={[
265
+
SupportedLanguage.CURL,
266
+
]}
267
+
/>
268
+
269
+
:::caution
270
+
At the moment, this feature is only available on the API (v1.10.0). Supported SDKs will follow shortly after.
271
+
:::
272
+
273
+
Similarly, you can use `on_missing: "ignore"` when deleting tuples that might not exist.
274
+
275
+
<WriteRequestViewer
276
+
skipSetup={true}
277
+
deleteRelationshipTuples={[
278
+
{
279
+
user: 'user:anne',
280
+
relation: 'writer',
281
+
object: 'document:Z'
282
+
},
283
+
]}
284
+
deleteOptions={{
285
+
on_missing: 'ignore',
286
+
}}
287
+
expectedResponse={{
288
+
data: {},
289
+
}}
290
+
allowedLanguages={[
291
+
SupportedLanguage.CURL,
292
+
]}
293
+
/>
294
+
295
+
The behavior of `on_duplicate: "ignore"` is more nuanced for tuples with conditions.
296
+
-**Identical Tuples**: If a tuple in the request is identical to an existing tuple (same user, relation, object, condition name, and condition context), it will be safely ignored.
297
+
-**Conflicting Tuples**: If a tuple key (user, relation, object) matches an existing tuple, but the condition name or parameters are different, this is a conflict. The write attempt will be rejected, and the entire transaction will fail with a `409 Conflict` error.
298
+
202
299
## Related Sections
203
300
204
301
<RelatedSection
205
302
description="Check the following sections for more on how to write your authorization data"
206
303
relatedLinks={[
304
+
{
305
+
title: 'Write API',
306
+
description: 'Learn more about the Write API options.',
307
+
link: '/api/service#Relationship%20Tuples/Write',
308
+
},
207
309
{
208
310
title: 'Managing User Access',
209
311
description: 'Learn about how to give a user access to a particular object.',
@@ -216,11 +318,5 @@ Assume that you want to delete user `user:anne`'s `reader` relationship with obj
216
318
link: '../interacting/managing-group-access',
217
319
id: '../interacting/managing-group-access.mdx',
218
320
},
219
-
{
220
-
title: 'Transactional Writes',
221
-
description: 'Learn about how to update multiple relations within the same API call.',
0 commit comments