examples

Examples and wiring

This page shows small copy-pasteable examples demonstrating how to implement a RefreshFunc and wire the generic in-memory adapter to the HTTP server.

  1. An example adapter refresh function (see internal/adapter/examples/examples_adapter.go):
  • Implements func(ctx context.Context) ([]model.Project, []model.Customer, []model.Person, error).
  • Returns normalized model.Project, model.Customer, and model.Person slices. The generic adapter will clamp/validate fields (for example Progress is clamped to 0..100).
  1. Wire it into the example server in cmd/exampleservice:

After creating the adapter with examples.NewExampleAdapter(), call Refresh(context.Background()) once to populate the in-memory store, then start the HTTP server. Handlers use the Adapter interface and remain agnostic of upstream details.

  1. Example curl calls:

List projects:

1
curl -sS localhost:8080/projects | jq .

Get a project by id:

1
curl -sS localhost:8080/projects/proj-ex | jq .

Filter by customer id (single or comma-separated):

1
2
curl -sS 'localhost:8080/projects?customer_id=cust-ex' | jq .
curl -sS 'localhost:8080/projects?customer_id=cust-ex,other-id' | jq .

Sort by progress:

1
curl -sS 'localhost:8080/projects?sort=progress' | jq .
  1. Run the example service (fish-compatible env setting):
1
2
cd cmd/exampleservice
env PORT=8080 go run .

Analytics and stats

Status metadata (faceting) — counts respect scoping filters but ignore explicit status/active:

1
2
curl -sS 'localhost:8080/status-meta' | jq .
curl -sS 'localhost:8080/status-meta?q=alpha&customer_id=cust-ex' | jq .

Current snapshot stats (filters match /projects semantics):

1
2
3
curl -sS 'localhost:8080/stats' | jq .
curl -sS 'localhost:8080/stats?active=true&priority=high' | jq .
curl -sS 'localhost:8080/stats?q=demo' | jq .

Example response (abridged) from GET /stats:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
    "server_time": "2025-09-21T01:00:00Z",
    "totals": { "total_projects": 12, "active_projects": 9, "inactive_projects": 3, "backlog_projects": 2 },
    "by_status": [{ "value": "active", "count": 9, "active": true }, { "value": "planned", "count": 3, "active": false }],
    "by_priority": [{ "value": "high", "count": 5 }, { "value": "medium", "count": 4 }, { "value": "low", "count": 3 }],
    "progress": { "avg": 62.4, "p50": 60, "p90": 95 },
    "progress_distribution": [0,0,1,2,3,1,2,1,1,1],
    "service": { "name": "go-test-project", "version": "0.1.0" },
    "instance_id": "instance-1",
    "env": "prod"
}

Weekly rollups (when the sampler/rollup is enabled):

1
2
curl -sS 'localhost:8080/stats/weekly' | jq .
curl -sS 'localhost:8080/stats/weekly/2025-W38' | jq .

Notes

  • progress.avg/p50/p90 are computed over clamped [0,100] values.
  • durations may be omitted if timestamps are insufficient.
  • The example adapter is intentionally tiny and synchronous. Real upstream adapters typically run network calls and mapping logic inside the RefreshFunc. Prefer keeping mapping logic simple and letting the generic adapter handle cross-cutting concerns (clamping, filtering, sorting).

Startup Backfill (JetStream) — example wiring

If you enable JetStream export and startup backfill, the service will attempt to hydrate the in-memory weekly ring on boot. Example env and pseudocode:

Environment (example):

1
2
3
4
export NATS_URLS=nats://nats:4222
export NATS_AUTOPROVISION=true
export NATS_BACKFILL_ON_START=true
export NATS_BACKFILL_WEEKS=26

Pseudocode (example wiring in cmd/exampleservice/main.go):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// ...existing setup...
var backfiller api.WeeklyBackfiller
if os.Getenv("NATS_BACKFILL_ON_START") == "true" {
    backfiller = api.NewNATSBackfiller() // placeholder until JetStream implemented
} else {
    backfiller = api.NoopBackfiller{}
}

if backfiller != nil {
    weeks, _ := backfiller.Backfill(context.Background(), 26)
    // feed weeks into in-memory ring (adapter or server state)
}

Note: NewNATSBackfiller() is a placeholder that currently returns a no-op implementation; implement the JetStream pull consumer to enable real backfill.