Go SDK
github.com/runnev/runnev-go is the official Go SDK. Standard library only,
no external modules, Go 1.21+. Context-aware throughout; subscriptions deliver batches
on a channel.
Install
bash
go get github.com/runnev/runnev-go@v1.4.2Configure
go
import "github.com/runnev/runnev-go"
client := runnev.New(runnev.Options{
APIKey: os.Getenv("RUNNEV_API_KEY"), // required
BaseURL: "https://runnev.dev/v1", // default
Timeout: 30 * time.Second, // per unary request; not the subscribe stream
MaxRetries: 4, // retries on 429 / 5xx
})Publish
go
ctx := context.Background()
stream, err := client.CreateStream(ctx, runnev.CreateStreamParams{
Name: "orders-eu", RetentionSeconds: 86400,
})
// explicit sequence - idempotent, safe to retry
res, err := client.Publish(ctx, stream.ID, 41823, []runnev.Event{
{"type": "order.paid", "id": "o_5521", "amount": 1999},
})
_ = res.Cursor // 41823
// server-assigned sequence
_, err = client.PublishAuto(ctx, stream.ID, []runnev.Event{{"type": "tick"}})
// raw bytes for a raw-mode stream
_, err = client.PublishRaw(ctx, stream.ID, 9001, protobufBytes, "application/octet-stream")Subscribe
Subscribe returns a *Subscription exposing a receive-only channel, an
error accessor, and Close. It reconnects automatically, resuming from the
last sequence.
go
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
sub, err := client.Subscribe(ctx, stream.ID, runnev.SubscribeOptions{Cursor: "0"})
if err != nil {
log.Fatal(err)
}
defer sub.Close()
for batch := range sub.C {
fmt.Println(batch.Seq, batch.Events)
}
if err := sub.Err(); err != nil {
log.Println("subscription ended:", err)
}Error handling
go
res, err := client.Publish(ctx, id, seq, events)
if err != nil {
var rerr *runnev.Error
if errors.As(err, &rerr) {
log.Printf("code=%s status=%d request_id=%s", rerr.Code, rerr.Status, rerr.RequestID)
}
if errors.Is(err, runnev.ErrRateLimited) {
time.Sleep(rerr.RetryAfter)
}
}*runnev.Error carries Type, Code,
Message, RequestID, Status, and
DocURL. Sentinels for common codes
(ErrRateLimited, ErrStreamNotFound,
ErrInvalidAPIKey, and more) work with errors.Is.
API surface
| Method | Returns |
|---|---|
CreateStream(ctx, CreateStreamParams) | (*Stream, error) |
ListStreams(ctx, ListParams) | (*StreamPage, error) |
GetStream(ctx, id) | (*Stream, error) |
DeleteStream(ctx, id) | error |
Publish(ctx, id, seq, events) | (*PublishResult, error) |
PublishRaw(ctx, id, seq, data, contentType) | (*PublishResult, error) |
PublishAuto(ctx, id, events) | (*PublishResult, error) |
Cursor(ctx, id) | (*CursorInfo, error) |
Batch(ctx, id, seq) | (*Batch, error) |
Subscribe(ctx, id, SubscribeOptions) | (*Subscription, error) |
Runnable examples: examples/publish and examples/subscribe.