Skip to content

Extensions Overview

traverse extensions add optional capabilities that are not part of the core OData client. Each extension is a separate Go module to keep the core dependency-free.

Available extensions

Extension Module Description
SAP ext/sap CSRF tokens, SAP error parsing, BTP/XSUAA token exchange
OAuth2 ext/oauth2 OAuth2 token management and automatic refresh
Prometheus ext/prometheus Request metrics exposed as Prometheus counters/histograms
OpenTelemetry ext/otel Distributed tracing with OTel spans
Cache ext/cache Response caching with ETag and Cache-Control awareness
Stale Cache ext/cache/stale Stale-while-revalidate cache for metadata and reference data
Webhooks ext/webhooks OData v4 webhook subscription lifecycle and dispatch
GraphQL Bridge ext/graphql Translate OData queries to GraphQL automatically
Microsoft Graph ext/graph Microsoft Graph API helpers
Azure Event Grid ext/azure Publish OData entity change events to Azure Event Grid
Offline Store ext/offline Persistent local JSON cache for offline query support
Dataverse ext/dataverse Microsoft Dataverse OData adapter (Power Platform / Dynamics 365)
OpenAPI Export ext/openapi Convert OData *Metadata to an OpenAPI 3.1 document
Audit Trail ext/audit Record every OData request/response for compliance

Installing extensions

Each extension is a separate module:

go get github.com/jhonsferg/traverse/ext/sap@latest
go get github.com/jhonsferg/traverse/ext/otel@latest

Using multiple extensions

Extensions are composable. Pass them via traverse.Config.Extension or chain with traverse.Chain:

client := traverse.New(traverse.Config{
    BaseURL: "https://api.example.com/odata/",
    Extension: traverse.Chain(
        sap.Extension(),
        otel.Extension(otel.Config{ServiceName: "my-service"}),
        prometheus.Extension(),
    ),
})

Writing a custom extension

Implement the traverse.Extension interface:

type Extension interface {
    WrapTransport(http.RoundTripper) http.RoundTripper
    OnRequest(ctx context.Context, req *http.Request) error
    OnResponse(ctx context.Context, req *http.Request, resp *http.Response) error
}

Extensions can wrap the transport (for low-level control) or use hooks (for request/response inspection).