Skip to content
Plugins (190)

grpc

stable

Encode and decode Protocol Buffer wire format fields and gRPC frames, and build gRPC HTTP/2 request metadata.

use plugin grpc
19 functions Networking
Runs with the native Zolo host

Plugin snippets can be edited in the Playground, but native capabilities are executed locally with the Zolo CLI.

/ filter jk navigate Esc clear
Functions (19)
  1. encode_varint Encode integer as protobuf LEB128 varint bytes
  2. decode_varint Decode varint bytes to value and bytes consumed
  3. encode_string_field Encode a protobuf string field
  4. encode_int_field Encode a protobuf integer field
  5. decode_fields Decode all fields from a protobuf message
  6. encode_grpc_frame Wrap message bytes in a gRPC length-prefixed frame
  7. decode_grpc_frame Unwrap a gRPC frame into header and message
  8. build_grpc_request Build gRPC HTTP/2 request metadata and body
  9. parse_grpc_status Extract status code and message from response headers
  10. status_name Map a gRPC status code to its canonical name
  11. encode_bytes_field Encode a protobuf bytes/embedded-message field
  12. encode_map Encode protobuf map entries
  13. decode_map Decode protobuf map entries
  14. encode_fixed32_field Encode a 32-bit fixed-width field
  15. encode_fixed64_field Encode a 64-bit fixed-width field
  16. concat_bytes Concatenate two byte sequences
  17. encode_float_field Encode a protobuf float field
  18. encode_double_field Encode a protobuf double field
  19. encode_bool_field Encode a protobuf bool field

From import to result

  1. 01Import only what you use
  2. 02Copy the smallest example
  3. 03Run it with the Zolo CLI

Overview

grpc is a low-level toolkit for the Protocol Buffers wire format and the gRPC framing layer, built entirely on plain byte sequences. It has no client of its own and opens no sockets: every function either produces bytes (the encoded form of a protobuf field, a map, or a gRPC frame) or consumes bytes and returns a decoded table. Because each encoder emits a self-contained chunk for a single field, you assemble a full message by concatenating those chunks with concat_bytes, wrap the result in a gRPC length-prefixed frame, and pair it with the HTTP/2 metadata from build_grpc_request.

The mental model is bottom-up: encode individual fields (encode_string_field, encode_int_field, the encode_*_field family), glue them together, frame the message with encode_grpc_frame, send it over your own HTTP/2 transport, then read the reply back with decode_grpc_frame, decode_fields, and parse_grpc_status / status_name. Reach for it whenever you need to speak gRPC or read and write protobuf bytes without depending on generated stubs.

Common patterns

Build a multi-field protobuf message and wrap it in a gRPC request:

use plugin grpc::{encode_string_field, encode_int_field, concat_bytes, build_grpc_request}

let body = concat_bytes(encode_string_field(1, "Alice"), encode_int_field(2, 30))
let req = build_grpc_request("user.UserService", "CreateUser", body)
print("POST {req["path"]} ({req["content_type"]})")

Frame a message, then decode the frame and its fields on the other side:

use plugin grpc::{encode_string_field, encode_grpc_frame, decode_grpc_frame, decode_fields}

let frame = encode_grpc_frame(encode_string_field(1, "ping"), false)
let unwrapped = decode_grpc_frame(frame)
let fields = decode_fields(unwrapped["message"])
print("field {fields[0]["field_number"]} is wire type {fields[0]["wire_type"]}")

Inspect a gRPC status returned in response trailers:

use plugin grpc::{parse_grpc_status, status_name}

let trailers = #{"grpc-status": "5", "grpc-message": "user not found"}
let status = parse_grpc_status(trailers)
print("{status_name(status["code"])}: {status["message"]}")

Encode integer as protobuf LEB128 varint bytes

Encodes a non-negative integer using protobuf LEB128 variable-length encoding.

use plugin grpc::{encode_varint}

let b = encode_varint(300)
print(b.len())

Decode varint bytes to value and bytes consumed

Decodes the first varint from bytes and returns a table with value (int) and bytes_read (int).

use plugin grpc::{encode_varint, decode_varint}

let b = encode_varint(300)
let result = decode_varint(b)
print(result["value"])
print(result["bytes_read"])

Encode a protobuf string field

Encodes a string as a length-delimited protobuf field (wire type 2) for the given field number.

use plugin grpc::{encode_string_field}

let b = encode_string_field(1, "hello")
print(b.len())

Encode a protobuf integer field

Encodes an integer as a varint protobuf field (wire type 0).

use plugin grpc::{encode_int_field}

let b = encode_int_field(2, 42)
print(b.len())

Decode all fields from a protobuf message

Decodes all fields from a protobuf-encoded message. Returns a list of {field_number, wire_type, data} entries.

use plugin grpc::{encode_string_field, encode_int_field, concat_bytes, decode_fields}

let msg = concat_bytes(encode_string_field(1, "Alice"), encode_int_field(2, 30))
let fields = decode_fields(msg)
print(fields[0]["field_number"])

Iterate every decoded field to print its wire type alongside its number:

use plugin grpc::{encode_string_field, encode_int_field, encode_bool_field, concat_bytes, decode_fields}

let msg = concat_bytes(concat_bytes(encode_string_field(1, "Bob"), encode_int_field(2, 7)), encode_bool_field(3, true))
let fields = decode_fields(msg)
for field in fields {
  print("#{field["field_number"]} wire={field["wire_type"]}")
}

Wrap message bytes in a gRPC length-prefixed frame

Wraps message bytes in a gRPC 5-byte length-prefixed frame: [compressed:1][length:4][message:N].

use plugin grpc::{encode_string_field, encode_grpc_frame, decode_grpc_frame}

let msg = encode_string_field(1, "ping")
let frame = encode_grpc_frame(msg, false)
let decoded = decode_grpc_frame(frame)
print(decoded["compressed"])
print(decoded["length"])

Unwrap a gRPC frame into header and message

Parses a gRPC frame and returns {compressed, length, message}. Errors if the input is shorter than five bytes or is truncated relative to its declared length.

use plugin grpc::{encode_int_field, encode_grpc_frame, decode_grpc_frame}

let frame = encode_grpc_frame(encode_int_field(1, 99), false)
let result = decode_grpc_frame(frame)
print(result["length"])

Build gRPC HTTP/2 request metadata and body

Builds the HTTP/2 metadata needed for a gRPC call: path, content_type, te, grpc_encoding, and body (the message already wrapped in an uncompressed frame).

use plugin grpc::{encode_string_field, build_grpc_request}

let msg = encode_string_field(1, "world")
let req = build_grpc_request("helloworld.Greeter", "SayHello", msg)
print(req["path"])
print(req["content_type"])

Extract status code and message from response headers

Reads grpc-status, grpc-message, and grpc-status-details-bin from a response headers table (keys are matched case-insensitively). Returns {code, message, details}, with code defaulting to -1 when no status header is present.

use plugin grpc::{parse_grpc_status, status_name}

let headers = #{"grpc-status": "0", "grpc-message": "OK"}
let status = parse_grpc_status(headers)
print(status_name(status["code"]))

Map a gRPC status code to its canonical name

Maps a gRPC status integer code (0–16) to its canonical name such as "OK", "NOT_FOUND", or "UNAUTHENTICATED". Unknown codes return "UNKNOWN".

use plugin grpc::{status_name}

print(status_name(5))
print(status_name(0))

Encode a protobuf bytes/embedded-message field

Encodes a byte sequence as a length-delimited protobuf field (wire type 2). Use this for bytes fields and for nesting an already-encoded embedded message.

use plugin grpc::{encode_string_field, encode_bytes_field, decode_fields}

let inner = encode_string_field(1, "nested")
let outer = encode_bytes_field(5, inner)
let fields = decode_fields(outer)
print(fields[0]["field_number"])

Encode protobuf map entries

Encodes a table of (key, value) pairs as a sequence of protobuf map entries. Each entry becomes a length-delimited message with field 1 as the key and field 2 as the value; string, integer, and bytes values are supported.

use plugin grpc::{encode_map, decode_map}

let encoded = encode_map(#{"name": "Alice", "city": "Berlin"})
let back = decode_map(encoded, "string", "string")
print(back["name"])

Decode protobuf map entries

Decodes a sequence of protobuf map entries back into a table. key_type and value_type select how each side is interpreted: "string", "int", or "bytes".

use plugin grpc::{encode_map, decode_map}

let encoded = encode_map(#{"retries": 3, "timeout": 30})
let settings = decode_map(encoded, "string", "int")
print(settings["timeout"])

Encode a 32-bit fixed-width field

Encodes an integer as a protobuf fixed32 field (wire type 5, four little-endian bytes). Unlike a varint, the width is constant regardless of the value.

use plugin grpc::{encode_fixed32_field}

let b = encode_fixed32_field(4, 1000)
print(b.len())

Encode a 64-bit fixed-width field

Encodes an integer as a protobuf fixed64 field (wire type 1, eight little-endian bytes).

use plugin grpc::{encode_fixed64_field}

let b = encode_fixed64_field(6, 9000000000)
print(b.len())

Concatenate two byte sequences

Concatenates two byte sequences. Useful for assembling multi-field protobuf messages before framing.

use plugin grpc::{encode_string_field, encode_int_field, concat_bytes}

let name_field = encode_string_field(1, "Alice")
let age_field = encode_int_field(2, 30)
let msg = concat_bytes(name_field, age_field)
print(msg.len())

Encode a protobuf float field

Encodes a number as a protobuf float field (wire type 5, 32-bit IEEE-754). The value is narrowed to single precision.

use plugin grpc::{encode_float_field}

let b = encode_float_field(7, 3.14)
print(b.len())

Encode a protobuf double field

Encodes a number as a protobuf double field (wire type 1, 64-bit IEEE-754), preserving full double precision.

use plugin grpc::{encode_double_field, concat_bytes, encode_string_field, encode_grpc_frame}

let payload = concat_bytes(encode_string_field(1, "EUR"), encode_double_field(2, 19.99))
let frame = encode_grpc_frame(payload, false)
print(frame.len())

Encode a protobuf bool field

Encodes a boolean as a varint protobuf field (0 for false, 1 for true).

use plugin grpc::{encode_bool_field}

let b = encode_bool_field(3, true)
print(b.len())

Global index

Find your way through Zolo

Try an idea

Start here

9 results

9 results

en