diff --git a/astro.config.mjs b/astro.config.mjs index bca035d9..6051b2c8 100755 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -94,6 +94,12 @@ export default defineConfig({ "concepts/architecture/async-execution", ] }, + { + label: "Commands API", + items: [ + "commands/valkey-string" + ] + }, { label: "Core Features", collapsed: true, diff --git a/src/content/docs/commands/valkey-string.mdx b/src/content/docs/commands/valkey-string.mdx new file mode 100644 index 00000000..3402eae9 --- /dev/null +++ b/src/content/docs/commands/valkey-string.mdx @@ -0,0 +1,192 @@ +--- +title: Working with Strings and Binary Data +description: Learn how to work with UTF-8 strings and binary data in Valkey GLIDE clients. +--- + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + +Valkey strings store sequences of bytes, which may include text, serialized objects, or binary arrays. GLIDE clients provide language-specific ways to handle both UTF-8 encoded strings and binary data when passing arguments to commands or receiving responses. + +## String API + + + Python uses `TEncodable` as a union type that accepts either: + + 1. `str`: for UTF-8 encoded strings + 2. `bytes`: for binary data + + #### Type Definition + + ```python + TEncodable = Union[str, bytes] + ``` + + #### Usage + + Commands accept both `str` and `bytes` arguments. When passing strings, they are automatically encoded to UTF-8. When you need binary data, pass `bytes` directly. + + ```python + # Using strings (automatically encoded) + await client.set("key", "value") + result = await client.get("key") # Returns bytes: b'value' + + # Using bytes directly + await client.set(b"key", b"binary_value") + result = await client.get(b"key") # Returns bytes: b'binary_value' + + # Converting between str and bytes + key = "my_key" + await client.set(key.encode(), b"value") # str to bytes with .encode() + result = await client.get(key.encode()) + decoded = result.decode() # bytes to str with .decode() + ``` + + #### Return Values + + Most commands return `bytes` by default. Use `.decode()` to convert to `str` when needed. + + + Valkey strings can be passed and received in two ways: + + 1. `String`: for common case UTF-8 converted strings + 2. `GlideString`: to pass `byte[]` data using a container object + + #### API Rules + + * Command signatures either take and return `String`'s or `GlideString`'s, but not both. + * `String`'s are returned if the commands are passed in `String`'s. e.g `CompletableFuture mget(String[] keys)` + * `GlideString`'s are returned if the commands are passed in `GlideString`'s. e.g `CompletableFuture mget(GlideString[] keys)` + + Arguments for commands that require a `String` can also be substituted with `GlideString` in order to pass in or return a binary value. + + #### Usage + + * `gs()` is a static constructor that can be called with a `byte[]` or `String` argument to convert to `GlideString`. For example: + + ```java + byte[] byteKey = Base64.getDecoder().decode("byteKey"); + client.set(gs(byteKey), gs("GlideString value")).get(); + ``` + + * A `GlideString byte[]` object can be converted to UTF-8 `String` by calling `.getString()` on the `GlideString` object. For example: + + ```java + client.get(gs(byteKey)).get(); // "GlideString value" as a GlideString + client.get(gs(byteKey)).get().getString(); // "GlideString value" as a String + ``` + + + `GlideString` is a type that maps to Valkey strings and represents either: + + 1. `string`: as a UTF-8 encoded string + 2. `Buffer`: as a `byte[]` + + #### Usage + + Commands accept both `string` and `Buffer` arguments: + + ```ts + import {GlideClient} from "@valkey/valkey-glide"; + + // Using strings (UTF-8) + await client.set("key", "value"); + const result = await client.get("key"); // Returns GlideString (string | Buffer) + + // Using Buffer for binary data + const binaryKey = Buffer.from([0x01, 0x02, 0x03, 0xFE]); + const binaryValue = Buffer.from([0xDE, 0xAD, 0xBE, 0xEF]); + + await client.set(binaryKey, binaryValue); + const value = await client.get(binaryKey); // Returns Buffer + + // Converting between string and Buffer + const buffer = Buffer.from("text", "utf-8"); + const text = buffer.toString("utf-8"); + ``` + + #### Return Types + + * Commands use `string` instead of `GlideString` as the return type if they contain a simple string value (simple strings in Valkey are always UTF-8 encoded strings). For example, `type` command returns one of pre-defined strings, or `set` command which returns `"OK"`. + * Commands use `Buffer` as the return type when they always contain binary data. For example, `dump` and `functionDump` commands. + * Most commands use `GlideString` as the common return type. + + #### Decoder + + While Node.js defaults to string responses, you have full control over the return data type. + You can use the `DecoderOption` property to toggle between string and byte formats for individual commands. + + Additionally, you can define a global preference during client creation, which acts as the default for any command that doesn't have a specific decoder argument. + + `Decoder` is an optional parameter for commands with two options + + 1. `Bytes`: decodes the response into a `Buffer` (byte array). + 2. `String`: decodes the response into a string. + + If `Decoder` is not configured, `Decoder.String` will be used as the default decoder. + + :::note + Using the `Decoder.String` to convert Non-UTF-8 encoded Valkey strings can lead to errors unrecoverable data lost. See: [#2221](https://github.com/valkey-io/valkey-glide/discussions/2221). + ::: + + #### Example Usage + + Here is an example of command implementation to outline arguments using [`DecoderOption`](https://github.com/valkey-io/valkey-glide/blob/79fdec50bbef4310cb12e46a69f14c18378afb44/node/src/BaseClient.ts#L295) and response type: + + ```typescript + public getdel( + key: GlideString, + options?: DecoderOption, + ): Promise + ``` + + Here's a simple example demonstrating how to use `Decoder` in command API and `Buffer.from()` to encode binary data: + + ```typescript + expect(await client.set(key, value)).toEqual("OK"); + expect(await client.getdel(key)).toEqual(value); + + const valueEncoded = Buffer.from(value); + expect(await client.set(key, value)).toEqual("OK"); + expect(await client.getdel(key, { decoder: Decoder.Bytes })).toEqual( + valueEncoded, + ); + ``` + + + Go uses native `string` type for all Valkey string operations. Go strings can contain arbitrary bytes, including binary data. + + #### Usage + + Commands accept `string` arguments and return `string` values. To work with binary data, convert between `[]byte` and `string`: + + ```go + import ( + "context" + "github.com/valkey-io/valkey-glide/go/v2" + ) + + // Using regular strings + result, err := client.Set(context.Background(), "key", "value") + value, err := client.Get(context.Background(), "key") + + // Using binary data - convert []byte to string + binaryKey := string([]byte{0x01, 0x02, 0x03, 0xFE}) + binaryValue := string([]byte{0xDE, 0xAD, 0xBE, 0xEF}) + + result, err := client.Set(context.Background(), binaryKey, binaryValue) + + // Get returns string, convert back to []byte if needed + value, err := client.Get(context.Background(), binaryKey) + if !value.IsNil() { + binaryData := []byte(value.Value()) + } + ``` + + #### Type Conversion + + * `string([]byte{...})` - Convert `[]byte` to `string` + * `[]byte(stringVar)` - Convert `string` to `[]byte` + + Go strings are immutable sequences of bytes and can safely represent binary data. + + diff --git a/src/content/docs/how-to/security/iam-integration.mdx b/src/content/docs/how-to/security/iam-integration.mdx index b518588c..cd8b7d6f 100644 --- a/src/content/docs/how-to/security/iam-integration.mdx +++ b/src/content/docs/how-to/security/iam-integration.mdx @@ -32,8 +32,8 @@ For GLIDE versions below 2.2, see the [guide](/how-to/security/iam-integration-u * **refreshIntervalSeconds (Optional)**: How often to refresh the token. Default is **300 seconds (5 minutes)** ## Examples - - + + ```python from glide import ( GlideClusterClient, @@ -69,7 +69,7 @@ For GLIDE versions below 2.2, see the [guide](/how-to/security/iam-integration-u ... ``` - + ```java import java.util.Collections; @@ -106,7 +106,7 @@ For GLIDE versions below 2.2, see the [guide](/how-to/security/iam-integration-u ... ``` - + ```ts // Automatically regenerates the token every 5 mins const client = await GlideClusterClient.createClient({