Context-aware.
Zero deps.
Standard library only. context.Context on every call. Struct-based options. Idiomatic error handling with sentinel errors and wrapped types.
go get.
That is it.
Zero transitive dependencies. The SDK uses net/http, encoding/json, and crypto/hmac from the standard library. Nothing else.
Functional options.
Idiomatic Go.
Construct with functional options. Pass context.Context to every call for deadlines, cancellation, and tracing propagation.
Struct params.
Pointer optionals.
Optional fields use pointer types with helper constructors (relays.String, relays.Int). Required fields are value types. No ambiguity.
Auto-paginate.
Or manual.
Use the iterator to auto-paginate through all results, or manage pages manually with Page and PerPage params. Both patterns are first-class.
// Auto-paginate through all records
iter := client.Records.ListAll(ctx, "example.com", nil)
for iter.Next() {
record := iter.Current()
fmt.Printf("%s %s -> %s
",
record.Type, record.Name, record.Content)
}
if err := iter.Err(); err != nil {
return fmt.Errorf("iterate records: %w", err)
}
// Manual pagination
page1, err := client.Records.List(ctx, "example.com",
&relays.ListRecordsParams{
Page: relays.Int(1),
PerPage: relays.Int(100),
},
)
// page1.Meta.Total => 247
// page1.Meta.Page => 1errors.Is.
errors.As.
Sentinel errors for common cases. Structured error types for details. All errors implement the standard error interface and support unwrapping.
_, err := client.Records.Create(ctx, zone, params)
// Sentinel errors
if errors.Is(err, relays.ErrNotFound) {
// Zone does not exist
}
if errors.Is(err, relays.ErrRateLimit) {
// Back off and retry
}
// Structured error details
var validErr *relays.ValidationError
if errors.As(err, &validErr) {
fmt.Println(validErr.Field) // "content"
fmt.Println(validErr.Reason) // "invalid IPv4"
}
var rateErr *relays.RateLimitError
if errors.As(err, &rateErr) {
time.Sleep(rateErr.RetryAfter)
}