Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e5c00bb
Add Duplicate Writes documentation
tylernix Sep 10, 2025
f4bb1c5
Add Duplicate Writes documentation
tylernix Sep 10, 2025
5d6b97c
Fix linting errors in WriteRequestViewer
tylernix Sep 10, 2025
5ec0c9d
Apply manual fixes to duplicate-writes documentation
tylernix Sep 10, 2025
ab18b95
Add Duplicate Writes reference to interacting overview
tylernix Sep 10, 2025
da0d168
Remove redundant write API documentation and streamline tuple managem…
tylernix Sep 12, 2025
70d4f41
Enhance documentation with advanced tuple management and fix relation…
tylernix Sep 12, 2025
723cd19
Revert configuration.mdx changes to focus PR on tuple management docu…
tylernix Sep 12, 2025
ccefcf8
quick word fixes
tylernix Sep 12, 2025
032c06a
Revert file name from add-tuples.mdx back to update-tuples.mdx
tylernix Sep 16, 2025
227a8a9
quick fix
tylernix Sep 16, 2025
7d33e1b
Add auto-generated configuration constants and ConfigValue component
tylernix Sep 16, 2025
7aa3d8c
quick fix
tylernix Sep 16, 2025
57bbded
Fix Prettier formatting issues
tylernix Sep 16, 2025
e925c23
Fix formatting issue in auto-generated constants
tylernix Sep 16, 2025
2ba5d78
Implement generic product-config system for multi-tenant documentation
tylernix Sep 17, 2025
3947bd0
quick title fix
tylernix Sep 17, 2025
9d9447a
Remove configuration.mdx changes from PR
tylernix Sep 17, 2025
ab7802c
quick title fix
tylernix Sep 17, 2025
5998a49
Remove ConfigValue component from this PR
tylernix Sep 17, 2025
62b2d61
Merge branch 'main' into feature/duplicate-writes-docs-v3
tylernix Oct 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ It offers an HTTP API, a gRPC API, and has SDKs for programming languages includ
- [Manage Group Access](./content/interacting/managing-user-access.mdx)
- [Manage Group Membership](./content/interacting/managing-group-membership.mdx)
- [Manage Relationships Between Objects](./content/interacting/managing-relationships-between-objects.mdx)
- [Transactional Writes](./content/interacting/transactional-writes.mdx)
- [Relationship Queries](./content/interacting/relationship-queries.mdx)
- [Get Tuple Changes](./content/interacting/read-tuple-changes.mdx)
- [Search with Permissions](./content/interacting/search-with-permissions.mdx)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: Update Relationship Tuples
title: Add Relationship Tuples
Comment thread
tylernix marked this conversation as resolved.
Outdated
sidebar_position: 3
slug: /getting-started/update-tuples
description: Updating system state by writing and deleting relationship tuples
slug: /getting-started/add-tuples
description: Basic introduction to adding and deleting relationship tuples
Comment thread
tylernix marked this conversation as resolved.
Outdated
---

import {
Expand All @@ -20,11 +20,11 @@ import {
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Update Relationship Tuples
# Add Relationship Tuples

<DocumentationNotice />

This section will illustrate how to update _<ProductConcept section="what-is-a-relationship-tuple" linkName="relationship tuples" />_.
This is a basic introduction to adding and deleting _<ProductConcept section="what-is-a-relationship-tuple" linkName="relationship tuples" />_.
Comment thread
tylernix marked this conversation as resolved.
Outdated

## Before you start

Expand Down Expand Up @@ -87,13 +87,13 @@ This section will illustrate how to update _<ProductConcept section="what-is-a-r

## Step by step

Assume that you want to add user `user:anne` to have relationship `reader` with object `document:Z`
Assume that you want to add user `user:anne` to have relationship `reader` with object `document:123`

```json
{
user: 'user:anne',
relation: 'reader',
object: 'document:Z',
object: 'document:123',
}
```

Comment thread
tylernix marked this conversation as resolved.
Expand Down Expand Up @@ -150,7 +150,7 @@ To add the relationship tuples, we can invoke the write API.
{
user: 'user:anne',
relation: 'reader',
object: 'document:Z',
object: 'document:123',
},
]}
skipSetup={true}
Expand All @@ -169,13 +169,13 @@ To add the relationship tuples, we can invoke the write API.

To delete relationship tuples, we can invoke the write API.

Assume that you want to delete user `user:anne`'s `reader` relationship with object `document:Z`
Assume that you want to delete user `user:anne`'s `reader` relationship with object `document:123`

```json
{
user: 'user:anne',
relation: 'reader',
object: 'document:Z',
object: 'document:123',
}
```

Expand All @@ -184,7 +184,7 @@ Assume that you want to delete user `user:anne`'s `reader` relationship with obj
{
user: 'user:anne',
relation: 'reader',
object: 'document:Z',
object: 'document:123',
},
]}
skipSetup={true}
Expand All @@ -199,11 +199,107 @@ Assume that you want to delete user `user:anne`'s `reader` relationship with obj
]}
/>

### 04. Writing and deleting relationship tuples in the same request

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
Comment thread
tylernix marked this conversation as resolved.
Outdated

For example, you might want to remove `user:anne` as a `editor` of `document:123` while simultaneously updating `user:anne` as an `reader` of `document:123`:

<WriteRequestViewer
relationshipTuples={[
{
user: 'user:anne',
relation: 'reader',
object: 'document:123',
},
]}
deleteRelationshipTuples={[
{
user: 'user:anne',
relation: 'editor',
object: 'document:123',
},
]}
skipSetup={true}
allowedLanguages={[
SupportedLanguage.JS_SDK,
SupportedLanguage.GO_SDK,
SupportedLanguage.DOTNET_SDK,
SupportedLanguage.PYTHON_SDK,
SupportedLanguage.JAVA_SDK,
SupportedLanguage.CLI,
SupportedLanguage.CURL,
]}
/>

This approach ensures that both operations succeed or fail together, maintaining transactional data consistency.
Comment thread
tylernix marked this conversation as resolved.

### 05. Ignoring duplicate tuples
Comment thread
tylernix marked this conversation as resolved.
Outdated

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.

This is particularly useful for high-volume data imports, migrations, or ensuring certain permissions exist without complex error handling logic.

For example, if you want to ensure `user:anne` has `reader` access to `document:123` without worrying about whether the relationship already exists in <productName format={ProductNameFormat.ShortForm}/>:

<WriteRequestViewer
Comment thread
tylernix marked this conversation as resolved.
Outdated
relationshipTuples={[
{
user: 'user:anne',
relation: 'reader',
object: 'document:123',
},
]}
writeOptions={{
on_duplicate: 'ignore',
}}
skipSetup={true}
allowedLanguages={[
SupportedLanguage.CURL,
]}
/>

:::caution
At the moment, this feature is only available on the API. Supported SDKs will follow shortly after.
Comment thread
tylernix marked this conversation as resolved.
Outdated
:::

Similarly, you can use `on_missing: "ignore"` when deleting tuples that might not exist.

<WriteRequestViewer
skipSetup={true}
deleteRelationshipTuples={[
{
user: 'user:anne',
relation: 'writer',
object: 'document:123',
},
]}
deleteOptions={{
on_missing: 'ignore',
}}
expectedResponse={{
data: {},
}}
allowedLanguages={[
SupportedLanguage.CURL,
]}
/>

The behavior of `on_duplicate: "ignore"` is more nuanced for tuples with conditions.
- **Identical Tuples**: If a tuple in the request is 100% identical to an existing tuple (same user, relation, object, condition name, and condition context), it will be safely ignored.
Comment thread
tylernix marked this conversation as resolved.
Outdated
- **Conflicting Tuples**: If a tuple key (user, relation, object) matches an existing tuple, but the condition is different, this is a conflict. The write attempt will be rejected, and the entire transaction will fail with a `409 Conflict` error.
Comment thread
tylernix marked this conversation as resolved.
Outdated


## Related Sections

<RelatedSection
description="Check the following sections for more on how to write your authorization data"
relatedLinks={[
{
title: 'Write API',
description: 'Learn more about the Write API options.',
link: '/api/service#Relationship%20Tuples/Write',
},
{
title: 'Managing User Access',
description: 'Learn about how to give a user access to a particular object.',
Expand All @@ -216,11 +312,5 @@ Assume that you want to delete user `user:anne`'s `reader` relationship with obj
link: '../interacting/managing-group-access',
id: '../interacting/managing-group-access.mdx',
},
{
title: 'Transactional Writes',
description: 'Learn about how to update multiple relations within the same API call.',
link: '../interacting/transactional-writes',
id: '../interacting/transactional-writes.mdx',
},
]}
/>
4 changes: 2 additions & 2 deletions docs/content/getting-started/framework.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ This section will illustrate how to integrate <ProductName format={ProductNameFo

1. <SdkSetupPrerequisite />
2. You have [installed the OpenFGA SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You know how to [perform a Check](./perform-check.mdx).
5. You have loaded `FGA_API_URL` and `FGA_STORE_ID` as environment variables.

Expand All @@ -41,7 +41,7 @@ This section will illustrate how to integrate <ProductName format={ProductNameFo

1. <SdkSetupPrerequisite />
2. You have [installed the OpenFGA SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You know how to [perform a Check](./perform-check.mdx).
5. You have loaded `FGA_API_URL` and `FGA_STORE_ID` as environment variables.

Expand Down
2 changes: 1 addition & 1 deletion docs/content/getting-started/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ The following will provide a step-by-step guide on how to get started with <Prod
{
title: 'Update Relationship Tuples',
description: 'Programmatically write authorization data to an {ProductName} store.',
to: 'getting-started/update-tuples',
to: 'getting-started/add-tuples',
},
{
title: 'Perform a Check',
Expand Down
12 changes: 6 additions & 6 deletions docs/content/getting-started/perform-check.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -45,7 +45,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -54,7 +54,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -63,7 +63,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -72,7 +72,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -88,7 +88,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a
<TabItem value={SupportedLanguage.CURL} label={languageLabelMap.get(SupportedLanguage.CURL)}>

1. <SdkSetupPrerequisite />
2. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
2. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
3. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand Down
12 changes: 6 additions & 6 deletions docs/content/getting-started/perform-list-objects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ This section describes how to perform a <ProductConcept section="what-is-a-list-

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -43,7 +43,7 @@ This section describes how to perform a <ProductConcept section="what-is-a-list-

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -52,7 +52,7 @@ This section describes how to perform a <ProductConcept section="what-is-a-list-

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -61,7 +61,7 @@ This section describes how to perform a <ProductConcept section="what-is-a-list-

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -70,7 +70,7 @@ This section describes how to perform a <ProductConcept section="what-is-a-list-

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -86,7 +86,7 @@ This section describes how to perform a <ProductConcept section="what-is-a-list-
<TabItem value={SupportedLanguage.CURL} label={languageLabelMap.get(SupportedLanguage.CURL)}>

1. <SdkSetupPrerequisite />
2. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
2. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
3. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand Down
12 changes: 6 additions & 6 deletions docs/content/getting-started/perform-list-users.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -44,7 +44,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -53,7 +53,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -62,7 +62,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -71,7 +71,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a

1. <SdkSetupPrerequisite />
2. You have [installed the SDK](./install-sdk.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
3. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
4. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand All @@ -87,7 +87,7 @@ This section will illustrate how to perform a <ProductConcept section="what-is-a
<TabItem value={SupportedLanguage.CURL} label={languageLabelMap.get(SupportedLanguage.CURL)}>

1. <SdkSetupPrerequisite />
2. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./update-tuples.mdx).
2. You have [configured the _authorization model_](./configure-model.mdx) and [updated the _relationship tuples_](./add-tuples.mdx).
3. You have loaded `FGA_STORE_ID` and `FGA_API_URL` as environment variables.

</TabItem>
Expand Down
Loading
Loading