From 6d08c7892b0e6af8bf8040fd2b786abf40f4f077 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Sun, 26 May 2024 21:15:18 -0400 Subject: [PATCH] Add API support for transaction metadata Reference: https://github.com/authzed/spicedb/issues/966 --- authzed/api/v1/error_reason.proto | 14 ++++++++++++++ authzed/api/v1/experimental_service.proto | 10 +++++++++- authzed/api/v1/permission_service.proto | 18 +++++++++++++++++- authzed/api/v1/watch_service.proto | 12 ++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/authzed/api/v1/error_reason.proto b/authzed/api/v1/error_reason.proto index 2591130..c1ced48 100644 --- a/authzed/api/v1/error_reason.proto +++ b/authzed/api/v1/error_reason.proto @@ -399,4 +399,18 @@ enum ErrorReason { // "metadata": { "disallowed_field": "subject_id" } // } ERROR_REASON_WILDCARD_NOT_ALLOWED = 28; + + // The request failed because the transaction metadata was too large. + // + // Example of an ErrorInfo: + // + // { + // "reason": "ERROR_REASON_TRANSACTION_METADATA_TOO_LARGE", + // "domain": "authzed.com", + // "metadata": { + // "metadata_byte_size": "1024", + // "maximum_allowed_metadata_byte_size": "512", + // } + // } + ERROR_REASON_TRANSACTION_METADATA_TOO_LARGE = 29; } \ No newline at end of file diff --git a/authzed/api/v1/experimental_service.proto b/authzed/api/v1/experimental_service.proto index 7566e9c..2cb2414 100644 --- a/authzed/api/v1/experimental_service.proto +++ b/authzed/api/v1/experimental_service.proto @@ -222,10 +222,18 @@ message BulkCheckPermissionResponseItem { // BulkImportRelationshipsRequest represents one batch of the streaming // BulkImportRelationships API. The maximum size is only limited by the backing // datastore, and optimal size should be determined by the calling client -// experimentally. +// experimentally. Any relationships within the same request are guaranteed to +// be written in a single transaction. If any of the relationships already +// exist, the transaction will fail and no relationships will be written. message BulkImportRelationshipsRequest { repeated Relationship relationships = 1 [ (validate.rules).repeated .items.message.required = true ]; + + + // optional_transaction_metadata is an optional field that can be used to store metadata about the transaction. + // If specified, this metadata will be supplied in the WatchResponse for the creations associated with + // this transaction. + google.protobuf.Struct optional_transaction_metadata = 2 [ (validate.rules).message.required = false ]; } // BulkImportRelationshipsResponse is returned on successful completion of the diff --git a/authzed/api/v1/permission_service.proto b/authzed/api/v1/permission_service.proto index 63905c1..94a526a 100644 --- a/authzed/api/v1/permission_service.proto +++ b/authzed/api/v1/permission_service.proto @@ -282,7 +282,8 @@ message Precondition { // WriteRelationshipsRequest contains a list of Relationship mutations that // should be applied to the service. If the optional_preconditions parameter // is included, all of the specified preconditions must also be satisfied before -// the write will be committed. +// the write will be committed. All updates will be applied transactionally, +// and if any preconditions fail, the entire transaction will be reverted. message WriteRelationshipsRequest { repeated RelationshipUpdate updates = 1 [ (validate.rules).repeated .items.message.required = true ]; @@ -290,6 +291,11 @@ message WriteRelationshipsRequest { repeated Precondition optional_preconditions = 2 [ (validate.rules).repeated .items.message.required = true ]; // To be bounded by configuration + + // optional_transaction_metadata is an optional field that can be used to store metadata about the transaction. + // If specified, this metadata will be supplied in the WatchResponse for the updates associated with this + // transaction. + google.protobuf.Struct optional_transaction_metadata = 3 [ (validate.rules).message.required = false ]; } message WriteRelationshipsResponse { ZedToken written_at = 1; } @@ -317,6 +323,11 @@ message DeleteRelationshipsRequest { // optional_allow_partial_deletions, if true and a limit is specified, will delete matching found // relationships up to the count specified in optional_limit, and no more. bool optional_allow_partial_deletions = 4; + + // optional_transaction_metadata is an optional field that can be used to store metadata about the transaction. + // If specified, this metadata will be supplied in the WatchResponse for the deletions associated with + // this transaction. + google.protobuf.Struct optional_transaction_metadata = 5 [ (validate.rules).message.required = false ]; } message DeleteRelationshipsResponse { @@ -662,6 +673,11 @@ message ResolvedSubject { message ImportBulkRelationshipsRequest { repeated Relationship relationships = 1 [ (validate.rules).repeated .items.message.required = true ]; + + // optional_transaction_metadata is an optional field that can be used to store metadata about the transaction. + // If specified, this metadata will be supplied in the WatchResponse for the creations associated with + // this transaction. + google.protobuf.Struct optional_transaction_metadata = 2 [ (validate.rules).message.required = false ]; } // ImportBulkRelationshipsResponse is returned on successful completion of the diff --git a/authzed/api/v1/watch_service.proto b/authzed/api/v1/watch_service.proto index 263985e..0daad5e 100644 --- a/authzed/api/v1/watch_service.proto +++ b/authzed/api/v1/watch_service.proto @@ -6,6 +6,7 @@ option java_package = "com.authzed.api.v1"; option java_multiple_files = true; import "google/api/annotations.proto"; +import "google/protobuf/struct.proto"; import "validate/validate.proto"; import "authzed/api/v1/core.proto"; @@ -58,6 +59,17 @@ message WatchRequest { // encoded in the watch response. The client can use the snapshot to resume // watching where the previous watch response left off. message WatchResponse { + // updates are the RelationshipUpdate events that have occurred since the + // last watch response. repeated RelationshipUpdate updates = 1; + + // changes_through is the ZedToken that represents the point in time + // that the watch response is current through. This token can be used + // in a subsequent WatchRequest to resume watching from this point. ZedToken changes_through = 2; + + // transaction_metadata is an optional field that returns the transaction metadata + // given to SpiceDB during the transaction that produced the changes in this response. + // This field may not exist if no transaction metadata was provided. + google.protobuf.Struct transaction_metadata = 3; }