go

module
v0.5.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2026 License: MIT

README

UDB Go SDK

UDB logo

UDB :: Universal Data Broker
gRPC data plane | native control plane | tenant/project scope guard
crate v0.5.21 | protocol v1.0.0

The Go SDK gives Go services a small client for a running UDB broker. It attaches UDB metadata for you, exposes DataBroker and auth helpers, and includes a version-matched CLI launcher.

Install

go get github.com/fahara02/udb/sdk/go@v0.5.21

Install the udb CLI launcher:

go install github.com/fahara02/udb/sdk/go/cmd/udb@v0.5.21

The launcher finds or downloads the matching UDB release binary, then forwards all arguments to it.

Export UDB Protos For Your App

From your application repo:

udb proto export --fmt

Now your app protos can import UDB annotations:

import "udb/core/common/v1/db.proto";

Run udb proto fmt after export or edits to keep long UDB field annotations on one line for easier review.

Connect And Query

import (
    "context"

    entityv1 "github.com/fahara02/udb/sdk/go/gen/udb/entity/v1"
    authzv1 "github.com/fahara02/udb/sdk/go/gen/udb/core/authz/services/v1"
    "github.com/fahara02/udb/sdk/go/udbclient"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
)

ctx := context.Background()
conn, err := grpc.NewClient(
    "localhost:50051",
    grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
    panic(err)
}
defer conn.Close()

meta := udbclient.Metadata{
    TenantID:             "acme",
    UserID:               "user-1",
    Purpose:              "web.request",
    CorrelationID:        "request-001",
    Scopes:               []string{"udb:read", "udb:write"},
    ServiceIdentity:      "billing.api",
    ProjectID:            "billing",
    ClientCatalogVersion: udbclient.ProtocolVersion,
}

udb := udbclient.New(conn, meta)
rows, err := udb.Select(ctx, &entityv1.SelectRequest{
    MessageType: "acme.billing.v1.Invoice",
    Limit:       50,
})
if err != nil {
    panic(err)
}
_ = rows

auth := udbclient.NewAuthClient(conn, meta)
allowed, decision, err := auth.Can(
    ctx,
    &authzv1.ResourceRef{MessageType: "acme.billing.v1.Invoice"},
    "read",
    "",
)
_, _ = allowed, decision
if err != nil {
    panic(err)
}

Storage (Upload And Download Files)

The Udb facade (udbclient.NewUdb) exposes a Storage client. UploadFile runs the register → presigned PUT → finalize sequence in one call; downloads come in two flavours — a presigned URL (the happy path, bytes never transit the broker) and a server-streaming byte fetch (the fallback for callers that cannot use a presigned HTTP URL).

udb, err := udbclient.NewUdb(ctx, udbclient.Config{Target: "localhost:50051"})
if err != nil {
    panic(err)
}
defer udb.Close()

// Log in and adopt the verified principal's canonical tenant/project.
_, err = udb.LoginAndAdoptTenant(ctx, &authnv1.LoginRequest{
    Username: "admin",
    Password: "admin",
})

// Upload bytes (register -> presigned PUT -> finalize).
up, err := udb.Storage.UploadFile(ctx, "greeting.txt", []byte("hello"),
    udbclient.WithContentType("text/plain"))
fileID := up.GetFile().GetFileId()

// Preferred: mint a time-limited presigned download URL (bytes stay out of the broker).
url, err := udb.Storage.DownloadFile(ctx, fileID, 15) // valid 15 minutes; 0 = server default

// Streaming fallback: stream the bytes back through the broker when a presigned
// URL can't be used. Reassembles the server-streaming DownloadFile chunk stream.
res, err := udb.Storage.DownloadFileBytes(ctx, fileID)
_ = res.Data // full file bytes; res.ContentType / res.TotalSize / res.ETag carry metadata

The facade signatures are:

func (f *StorageFacade) UploadFile(ctx context.Context, filename string, data []byte, opts ...UploadOption) (*storagev1.FinalizeUploadResponse, error)
func (f *StorageFacade) DownloadFile(ctx context.Context, fileID string, expiresInMinutes int32) (*storagev1.GetDownloadUrlResponse, error)
func (f *StorageFacade) DownloadFileBytes(ctx context.Context, fileID string, opts ...DownloadOption) (*DownloadResult, error)

Upload options: WithContentType, WithFileType, WithChecksum, WithETag. Download options: WithDownloadChunkSize (advisory server chunk size) and WithMaxDownloadBytes (caps the reassembled payload, failing closed before the buffer can grow past it). A full runnable program is in examples/storage.

Consistency, Idempotency Replay, And Typed Errors

A mutation returns a WriteReceipt; a follow-up read can carry a read fence built from it, or request an explicit consistency mode. A keyed replay-safe mutation that the broker deduplicated reports WasDuplicate (see docs/native-services.md for the full contract).

ent := udb.Entity("acme.billing.v1.Invoice", udbclient.EntityKey{"invoice_id"})

// Upsert surfaces the durable-idempotency replay flag on the result.
res, err := ent.Upsert(ctx, map[string]any{"invoice_id": "inv-1", "total_cents": 100})
if res.WasDuplicate { /* broker replayed a prior identical keyed write */ }

// Read-your-writes: fence the next read on the write's receipt.
receipt, _ := udbclient.ReceiptFromMutation(res.Response)
rc := &entityv1.RequestContext{TenantId: tenant, ProjectId: project}
udb.Metadata().AfterWrite(rc, receipt, 5000) // or package-level udbclient.AfterWrite

// Or pick an explicit consistency mode for an entity's reads.
rows, err := ent.WithConsistency(udbclient.ConsistencyReadYourWrites).
    Select(ctx, map[string]any{"invoice_id": "inv-1"})

Modes: ConsistencyStrong, ConsistencyReadYourWrites, ConsistencyBoundedStaleness, ConsistencyReplicaBounded, ConsistencyEventual, ConsistencyProjectionOk, ConsistencyCacheOk.

Retry contract: a replay-safe mutation is retried on transient errors only when the request carries a caller-supplied idempotency key — keyless mutations fail closed instead of risking a double apply. Typed error details decode from the udb-error-detail-bin trailer via Error.Detail() in this package.

Platform Services (Vault, Metering, Scheduler, …)

The control plane also ships Vault, Metering, Scheduler, Search, Webhook, Workflow, Lock, LiveQuery, Config, Backup, and Embedding services. They have no workflow facade yet — call them through the generated robustness layer:

import vaultv1 "github.com/fahara02/udb/sdk/go/gen/udb/core/vault/services/v1"

var reply vaultv1.EncryptResponse
err := udb.Generated.InvokeUnary(ctx,
    "/udb.core.vault.services.v1.VaultService/Encrypt",
    &vaultv1.EncryptRequest{TenantId: tenant, KeyName: "docs", Plaintext: "secret"},
    &reply)

Every RPC's full method path, retry class, and idempotency contract is listed in docs/generated/udb-native-contract.json.

Notes For Users

Use the udbclient package for normal app code. The gen/ packages contain the protobuf request and response types you pass to UDB; you do not need to run buf or protoc to install the SDK.

udbclient.ProtocolVersion is sent as x-udb-client-catalog-version so the broker can reject incompatible clients early.

Performance

The SDK uses a single long-lived gRPC channel — construct the *grpc.ClientConn (or use udbclient.NewUdb) once and reuse it across every RPC. Never open a new channel per call: a fresh channel forces a TCP+TLS+HTTP/2 handshake on every request, which dominates per-RPC latency.

For the best behaviour, append the generated layer's dial options to your own security options when you dial. They add:

  • Keepalive (Time: 30s, Timeout: 10s, PermitWithoutStream: true) so an idle connection stays warm instead of dropping to IDLE and re-handshaking.
  • Jittered exponential-backoff retry on UNAVAILABLE / RESOURCE_EXHAUSTED (4 attempts, 100ms base, full jitter, bounded by the call deadline), applied only to read-safe RPCs per the proto operation_kind.
  • Metadata injection and typed error mapping.
gen := udbclient.NewGenerated(nil, udbclient.Options{})
conn, err := grpc.NewClient(
    "localhost:50051",
    append(
        []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())},
        gen.DialOptions()...,
    )...,
)

udbclient.NewUdb(ctx, cfg) wires these dial options in for you automatically.

Directories

Path Synopsis
cmd
udb command
Command udb is a version-matched launcher for the UDB control-plane CLI, bundled with the Go SDK.
Command udb is a version-matched launcher for the UDB control-plane CLI, bundled with the Go SDK.
examples
publish_cdc command
select command
storage command
upsert command
gen

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL