Skip to content

dexpace/go-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dexpace

Go SDKs Platform

The Go counterpart to dexpace/java-sdk and dexpace/python-sdk. It is an HTTP-client toolkit, not an HTTP client: it supplies the request/response plumbing — a composable pipeline of policies (retry, auth, logging, …) — that sits between application code and a transport.

The Go port leans on the standard library. Requests and responses are net/http types, the transport seam is satisfied by *http.Client, and bodies are plain io.Reader/io.ReadCloser. There is no reinvented HTTP model and no Okio-style I/O layer; the toolkit adds the composition seam on top of net/http, the way azcore and the AWS SDK for Go do.

client := dexpace.New(
    dexpace.WithRetry(retry.Options{MaxRetries: 3}),
    dexpace.WithCredential(cred, "https://api.example.com/.default"),
    dexpace.WithLogging(nil), // nil → slog.Default()
)

req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.example.com/v1/things", nil)
resp, err := client.Do(req)
if err != nil {
    return err
}
defer resp.Body.Close()
if rerr := httperr.FromResponse(resp); rerr != nil {
    return rerr // *httperr.ResponseError for any 4xx/5xx
}

Architecture

Layered bottom-up; each layer is importable on its own and depends only on the standard library.

Package Responsibility
pipeline The Policy / Transporter contract and the Pipeline that runs an ordered policy chain over an *http.Request. Request.Next advances the chain; Request.RewindBody replays the body for retries.
transport The default net/http-backed Transporter that terminates a pipeline.
retry Retry policy — exponential backoff with full jitter, Retry-After, body rewind.
idempotency Idempotency-key policy (default-on for POST).
auth TokenCredential contract and BearerTokenPolicy (HTTPS-only, cached).
logging Structured request/response logging via log/slog, with URL redaction.
instrumentation Vendor-neutral Tracer/Meter SPIs with no-op defaults, plus tracing and metrics policies.
redact Default-deny URL redactor (strips userinfo, redacts query values) shared by logs, traces, and errors.
httperr ResponseError for non-success responses; buffers and rewinds the body.
mediatype Immutable media-type value with parsing and common constants.
header Canonical HTTP header-name constants.
pagination Generic pagination as iter.Seq2 range-over-func iterators — cursor/token, page-number, and RFC 8288 Link-header strategies, with a WithMaxPages cap.
conditions Conditional- and range-request value types (ETag, Range, Conditions).
config Layered override → environment → default settings resolver; non-failing typed getters.
serde Serialization seam (Marshaler/Unmarshaler) with a JSON default, plus Tristate for PATCH payloads.
sse Server-Sent Events (text/event-stream) WHATWG parser + reconnecting Stream (Last-Event-ID replay); Client.EventStream runs it through the pipeline.
jsonl JSON Lines / NDJSON streaming decoder (iter.Seq2).
webhook Inbound webhook signature verification (constant-time HMAC + timestamp tolerance).
formdata Multipart/form-data request body builder (replayable; file uploads).
root dexpace Umbrella Client wiring the default policy stack.

Pipeline order

dexpace.New assembles policies outermost-first:

[errors] → client-identity → idempotency → retry → auth → [date] → [tracing] → [metrics] → logging → custom → transport

Retry wraps the inner policies, so auth re-runs (and may refresh its token) on every attempt and logging records each attempt. Build a custom order directly with pipeline.New(transport, policies...) when you need something else.

An Idempotency-Key is sent on POST requests by default (disable with WithoutIdempotency); WithDate is opt-in.

By default Client.Do follows net/http semantics, where a non-2xx status is not an error. WithErrors opts into the typed error model: Client.Do then returns a *httperr.ResponseError for non-2xx responses and a *httperr.TransportError for transport failures. It is off by default.

Observability

Tracing and metrics are opt-in and route through the instrumentation package's vendor-neutral SPIs (no-op by default, so nothing is emitted until you wire a backend):

  • WithTracing(tracer) — installs a tracing policy that emits a span per request via the instrumentation Tracer SPI and injects a W3C traceparent header.
  • WithMetrics(meter) — installs a metrics policy recording request duration and in-flight requests via the instrumentation Meter SPI.
  • WithRedactionAllowlist(params...) — preserves the listed query-param values in redacted URLs (logs and traces); all other query values are redacted by default.

URLs are redacted by default across logs, traces, and errors: userinfo is stripped and query values are redacted unless allowlisted with WithRedactionAllowlist.

Authentication and configuration

  • WithCredential(cred, scopes...) — authenticates requests with bearer tokens from a TokenCredential (HTTPS-only, cached).
  • WithTokenCache(cache) — shares a bearer-token cache (an auth.TokenCache, in-memory by default) across clients so a cached token is reused.
  • WithBasicAuth(username, password) — authenticates requests with HTTP Basic auth (HTTPS-only).
  • WithAPIKey(header, key) — sets an API-key header on every request (HTTPS-only).
  • WithDigestAuth(username, password) — authenticates requests with HTTP Digest Access Authentication, RFC 7616 (MD5/SHA-256, qop=auth; HTTPS-only).
  • WithConfig(cfg) — sources defaults from DEXPACE_* environment variables — DEXPACE_USER_AGENT, DEXPACE_MAX_RETRIES (0 or negative disables retries), DEXPACE_RETRY_BASE_DELAY, DEXPACE_HTTP_TIMEOUT (default transport only) — for settings not set explicitly; explicit options always win.

Streaming

Client.EventStream(ctx, req, opts...) returns an iter.Seq2[sse.Event, error] reconnecting Server-Sent Events stream that runs through the pipeline — every connection clones req, sets Accept: text/event-stream, and replays the Last-Event-ID after a mid-stream interruption, so auth, logging, and tracing run per connection. A non-2xx response or a transport failure on connect ends the stream with that error; cancel the request context to stop.

req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.example.com/v1/events", nil)
for ev, err := range client.EventStream(ctx, req) {
	if err != nil {
		log.Printf("stream ended: %v", err)
		break
	}
	fmt.Println(ev.Data)
}

Requirements

Go 1.26+. The module targets modern idioms: generics, range-over-func iterators (iter.Seq2), math/rand/v2, log/slog, and the min/max builtins.

Development

make check   # tidy + fmt + vet + lint + test (race + coverage)
make test    # go test -race -covermode=atomic ./...
make lint    # golangci-lint

The SDK ships zero third-party runtime dependencies; only the standard library is imported by non-test code. See CONTRIBUTING.md for conventions and CLAUDE.md for the enforced rules.

See CHANGELOG.md for release notes.

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors