Skip to content

Add runnable examples, each smoke-tested against a stub - #21

Open
garretpremo wants to merge 1 commit into
mainfrom
feat/examples
Open

garretpremo wants to merge 1 commit into
mainfrom
feat/examples

Conversation

@garretpremo

Copy link
Copy Markdown
Contributor

Refs #20. The issue was closed as not needed, but in-repo examples still help the repo: CI now breaks when an SDK change breaks a realistic program, newcomers have something they can run in one command, and the JS SDK has an examples/ directory too.

What's here

Four examples under examples/. Each is its own Gradle project with a short README, a run task, and a smoke test.

Example Shows
ticket-triage Keyed questions, models listing, and API errors; a port of the JS SDK's demo.ts
typed-routing Ask handles and an enum Choice, routed to a queue by an exhaustive switch
async-batch systemOneAsync fan-out with per-call options, a custom retry policy, and failures per item
spring-boot The starter behind POST /tickets/route, with TypeSafe failures mapped to 502/504 ProblemDetail
TYPESAFE_API_KEY=your-key ./gradlew :examples:ticket-triage:run
  • Testing: each example takes its client through run(TypeSafeClient), so its test points it at examples/support's in-process StubTypeSafeServer. The Spring test sets typesafe.base-url instead. ./gradlew build checks all four with no API key and no secrets in CI.
  • README samples: these are output from real runs against the API.
  • Publishing: the root build's shared block now configures only typesafe-sdk and typesafe-sdk-spring-boot-starter, so nothing under examples/ is published. A dry run of publishToMavenCentral touches only those two modules.
  • Java level: the examples target Java 17, the same as the SDK.

Follow-ups found while writing these (not in this PR)

  • Root README, Spring Boot section: typesafe.api-key=${TYPESAFE_API_KEY} doesn't fail fast when the variable is unset. Boot binds the literal ${TYPESAFE_API_KEY} as the key, so the first request gets a 401. ${TYPESAFE_API_KEY:}, as the starter's Javadoc describes, is the form that works.
  • Root README, Async section: an exceptionally callback receives a CompletionException wrapping the TypeSafeException, not the exception itself. Only get()/join() hand back the unwrapped cause.
  • Possible API additions: ChoiceAnswer.probability() for the chosen label, and a systemOne(state, RequestOptions, Ask...) overload so per-call options don't force the builder form.

Four examples under examples/, each its own Gradle project with a
README, a run task, and a smoke test:

- ticket-triage: keyed questions, models listing, and API errors; a
  port of the JavaScript SDK's demo.
- typed-routing: Ask handles and an enum Choice, routed to a queue by
  an exhaustive switch.
- async-batch: systemOneAsync fan-out with per-call options, a custom
  retry policy, and failures per item that don't sink the batch.
- spring-boot: the starter behind POST /tickets/route, with TypeSafe
  failures mapped to 502 or 504 ProblemDetail responses.

Each example takes its client through run(TypeSafeClient), so the tests
point it at examples/support's in-process stub, and ./gradlew build
checks every example with no API key. The README samples are output
from real runs.

The root build now configures only the two library modules, so nothing
under examples/ is published.

Refs #20
@garretpremo garretpremo mentioned this pull request Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant