cloudflare/endpoints/workerskv/
write_bulk.rs

1use crate::framework::endpoint::{EndpointSpec, Method, RequestBody};
2
3use crate::endpoints::workerskv::WorkersKvBulkResult;
4use crate::framework::response::ApiSuccess;
5use serde::{Deserialize, Serialize};
6
7/// Write multiple keys and values at once.
8///
9/// Body should be an array of up to 10,000 key-value pairs to be stored, along with optional expiration information.
10///
11/// Existing values and expirations will be overwritten.
12/// If neither expiration nor expiration_ttl is specified, the key-value pair will never expire.
13/// If both are set, expiration_ttl is used and expiration is ignored.
14///
15/// The entire request size must be 100 megabytes or less.
16///
17/// A `404` is returned if a write action is for a namespace ID the account doesn't have.
18///
19/// <https://developers.cloudflare.com/api/resources/kv/subresources/namespaces/methods/bulk_update/>
20#[derive(Debug)]
21pub struct WriteBulk<'a> {
22    pub account_identifier: &'a str,
23    pub namespace_identifier: &'a str,
24    pub bulk_key_value_pairs: Vec<KeyValuePair>,
25}
26
27impl EndpointSpec for WriteBulk<'_> {
28    type JsonResponse = WorkersKvBulkResult;
29    type ResponseType = ApiSuccess<Self::JsonResponse>;
30
31    fn method(&self) -> Method {
32        Method::PUT
33    }
34    fn path(&self) -> String {
35        format!(
36            "accounts/{}/storage/kv/namespaces/{}/bulk",
37            self.account_identifier, self.namespace_identifier
38        )
39    }
40    #[inline]
41    fn body(&self) -> Option<RequestBody> {
42        if self.bulk_key_value_pairs.len() > 10_000 {
43            panic!("Bulk write request must have 10,000 key-value pairs or less.");
44        }
45        // TODO: The entire request size must be 100 megabytes or less.
46        let body = serde_json::to_string(&self.bulk_key_value_pairs).unwrap();
47        Some(RequestBody::Json(body))
48    }
49    // default content-type is already application/json
50}
51
52// TODO: Does not reflect the API documentation, but having everything Optional doesn't make sense either
53#[serde_with::skip_serializing_none]
54#[derive(Serialize, Deserialize, Clone, Debug)]
55pub struct KeyValuePair {
56    pub key: String,
57    pub value: String,
58    pub expiration: Option<i64>,
59    pub expiration_ttl: Option<i64>,
60    pub base64: Option<bool>,
61}