Examples
Small, runnable Go programs that demonstrate common Pebble use cases. Copy them into a file and run with go run.
Example: a simple JSON API call with retries
Retries up to three times on transient failures, with the default exponential backoff:
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"github.com/example/pebble"
)
type weather struct {
City string `json:"city"`
Temperature float64 `json:"temperature_c"`
}
func main() {
client := pebble.New(pebble.Options{
MaxRetries: 3,
})
resp, err := client.Get(context.Background(), "https://api.weather.example/v1/current?city=Amsterdam")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
var w weather
if err := json.NewDecoder(resp.Body).Decode(&w); err != nil {
log.Fatal(err)
}
fmt.Printf("%s: %.1f°C\n", w.City, w.Temperature)
}
Example: posting JSON with a custom timeout
package main
import (
"bytes"
"context"
"encoding/json"
"log"
"time"
"github.com/example/pebble"
)
func main() {
client := pebble.New(pebble.Options{
Timeout: 5 * time.Second,
})
body, err := json.Marshal(map[string]any{
"event": "user.signup",
"email": "joris@example.com",
})
if err != nil {
log.Fatal(err)
}
resp, err := client.Post(
context.Background(),
"https://api.events.example/v1/track",
bytes.NewReader(body),
"application/json",
)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
}
Example: handling specific error types
package main
import (
"context"
"errors"
"log"
"github.com/example/pebble"
"github.com/example/pebble/pebbleerrors"
)
func main() {
client := pebble.New(pebble.Options{MaxRetries: 3})
_, err := client.Get(context.Background(), "https://flaky-api.example/v1/data")
if err != nil {
var timeoutErr *pebbleerrors.TimeoutError
var retryErr *pebbleerrors.RetryExhaustedError
switch {
case errors.As(err, &timeoutErr):
log.Printf("upstream timeout after %v", timeoutErr.Elapsed)
case errors.As(err, &retryErr):
log.Printf("upstream failed after %d attempts: %v", retryErr.Attempts, retryErr.LastError)
default:
log.Printf("unexpected error: %v", err)
}
return
}
}
Example: with OpenTelemetry tracing
package main
import (
"context"
"github.com/example/pebble"
)
func main() {
// Assuming you've already initialised your OpenTelemetry SDK
// and registered a tracer provider globally.
client := pebble.New(pebble.Options{
EnableTracing: true,
})
ctx, span := tracer.Start(context.Background(), "fetch-user-profile")
defer span.End()
resp, _ := client.Get(ctx, "https://api.users.example/v1/me")
defer resp.Body.Close()
}
There are a few more examples in the examples/ directory of the GitHub repository, including some that use Pebble as part of larger workflows.