pub struct PutObjectRequest {
pub store_id: String,
pub global_version: Option<i64>,
pub transaction_items: Vec<KeyValue>,
pub delete_items: Vec<KeyValue>,
}
Expand description
Request payload to be used for PutObject
API call to server.
Fields§
§store_id: String
store_id
is a keyspace identifier.
Ref: https://en.wikipedia.org/wiki/Keyspace_(distributed_data_store)
All APIs operate within a single store_id
.
It is up to clients to use single or multiple stores for their use-case.
This can be used for client-isolation/ rate-limiting / throttling on the server-side.
Authorization and billing can also be performed at the store_id
level.
global_version: Option<i64>
global_version
is a sequence-number/version of the whole store. This can be used for versioning
and ensures that multiple updates in case of multiple devices can only be done linearly, even
if those updates did not directly conflict with each other based on keys/transaction_items
.
If present, the write will only succeed if the current server-side global_version
against
the store_id
is same as in the request.
Clients are expected to store (client-side) the global version against store_id
.
The request must contain their client-side value of global_version
if global versioning and
conflict detection is desired.
For the first write of the store, global version should be ‘0’. If the write succeeds, clients
must increment their global version (client-side) by 1.
The server increments global_version
(server-side) for every successful write, hence this
client-side increment is required to ensure matching versions. This updated global version
should be used in subsequent PutObjectRequest
s for the store.
Requests with a conflicting version will fail with CONFLICT_EXCEPTION
as ErrorCode.
transaction_items: Vec<KeyValue>
Items to be written as a result of this PutObjectRequest
.
In an item, each key
is supplied with its corresponding value
and version
.
Clients can choose to encrypt the keys client-side in order to obfuscate their usage patterns.
If the write is successful, the previous value
corresponding to the key
will be overwritten.
Multiple items in transaction_items
and delete_items
of a single PutObjectRequest
are written in
a database-transaction in an all-or-nothing fashion.
All Items in a single PutObjectRequest
must have distinct keys.
Key-level versioning (Conditional Write):
Clients are expected to store a version
against every key
.
The write will succeed if the current DB version against the key
is the same as in the request.
When initiating a PutObjectRequest
, the request should contain their client-side version
for that key-value.
For the first write of any key
, the version
should be ‘0’. If the write succeeds, the client
must increment their corresponding key versions (client-side) by 1.
The server increments key versions (server-side) for every successful write, hence this
client-side increment is required to ensure matching versions. These updated key versions should
be used in subsequent PutObjectRequest
s for the keys.
Requests with a conflicting/mismatched version will fail with CONFLICT_EXCEPTION
as ErrorCode
for conditional writes.
Skipping key-level versioning (Non-conditional Write):
If you wish to skip key-level version checks, set the version
against the key
to ‘-1’.
This will perform a non-conditional write query, after which the version
against the key
is reset to ‘1’. Hence, the next PutObjectRequest
for the key
can be either
a non-conditional write or a conditional write with version
set to 1
.
Considerations for transactions:
Transaction writes of multiple items have a performance overhead, hence it is recommended to use
them only if required by the client application to ensure logic/code correctness.
That is, transaction_items
are not a substitute for batch-write of multiple unrelated items.
When a write of multiple unrelated items is desired, it is recommended to use separate
PutObjectRequest
s.
Consistency guarantee:
All PutObjectRequest
s are strongly consistent i.e. they provide read-after-write and
read-after-update consistency guarantees.
delete_items: Vec<KeyValue>
Items to be deleted as a result of this PutObjectRequest
.
Each item in the delete_items
field consists of a key
and its corresponding version
.
Key-Level Versioning (Conditional Delete):
The version
is used to perform a version check before deleting the item.
The delete will only succeed if the current database version against the key
is the same as
the version
specified in the request.
Skipping key-level versioning (Non-conditional Delete):
If you wish to skip key-level version checks, set the version
against the key
to ‘-1’.
This will perform a non-conditional delete query.
Fails with CONFLICT_EXCEPTION
as the ErrorCode if:
- The requested item does not exist.
- The requested item does exist but there is a version-number mismatch (in conditional delete) with the one in the database.
Multiple items in the delete_items
field, along with the transaction_items
, are written in a
database transaction in an all-or-nothing fashion.
All items within a single PutObjectRequest
must have distinct keys.
Implementations§
Source§impl PutObjectRequest
impl PutObjectRequest
Sourcepub fn global_version(&self) -> i64
pub fn global_version(&self) -> i64
Returns the value of global_version
, or the default value if global_version
is unset.
Trait Implementations§
Source§impl Clone for PutObjectRequest
impl Clone for PutObjectRequest
Source§fn clone(&self) -> PutObjectRequest
fn clone(&self) -> PutObjectRequest
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl Debug for PutObjectRequest
impl Debug for PutObjectRequest
Source§impl Default for PutObjectRequest
impl Default for PutObjectRequest
Source§impl Message for PutObjectRequest
impl Message for PutObjectRequest
Source§fn encoded_len(&self) -> usize
fn encoded_len(&self) -> usize
Source§fn encode<B>(&self, buf: &mut B) -> Result<(), EncodeError>
fn encode<B>(&self, buf: &mut B) -> Result<(), EncodeError>
Source§fn encode_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
fn encode_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
Source§fn encode_length_delimited<B>(&self, buf: &mut B) -> Result<(), EncodeError>
fn encode_length_delimited<B>(&self, buf: &mut B) -> Result<(), EncodeError>
Source§fn encode_length_delimited_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
fn encode_length_delimited_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
Source§fn decode<B>(buf: B) -> Result<Self, DecodeError>
fn decode<B>(buf: B) -> Result<Self, DecodeError>
Source§fn decode_length_delimited<B>(buf: B) -> Result<Self, DecodeError>
fn decode_length_delimited<B>(buf: B) -> Result<Self, DecodeError>
Source§fn merge<B>(&mut self, buf: B) -> Result<(), DecodeError>
fn merge<B>(&mut self, buf: B) -> Result<(), DecodeError>
self
. Read moreSource§fn merge_length_delimited<B>(&mut self, buf: B) -> Result<(), DecodeError>
fn merge_length_delimited<B>(&mut self, buf: B) -> Result<(), DecodeError>
self
.