Skip to content

docs(examples): rewrite the consumer examples as teaching material#15

Merged
MarketDataDev03 merged 2 commits into
mainfrom
15_improve_examples
Jun 26, 2026
Merged

docs(examples): rewrite the consumer examples as teaching material#15
MarketDataDev03 merged 2 commits into
mainfrom
15_improve_examples

Conversation

@MarketDataDev03

Copy link
Copy Markdown
Collaborator

docs(examples): rewrite the consumer examples as teaching material

Branch 15_improve_examples14_code_ajustment · 1 commit · 33 files · +1337 −3258
Stacked on the 14_code_ajustmentmain PR — merge that one first.

The old examples/consumer-test/ apps doubled as an external verification harness: they scripted
a mock server, asserted contracts (peak-in-flight == 50, every exception subtype, retry timing), and
wrapped each SDK call in Console helpers and per-call try/catch. Great for catching regressions,
but the actual SDK call was buried — not something a consumer could read and copy.

This PR replaces them with examples that teach. Each file is a small, runnable program optimized
for reading: plain System.out.println, a single top-level try, the most common calls per
resource, and short comments explaining why. They consume the published artifact via mavenLocal,
so what you read is the real public API. Net −1921 lines.

What changed

  • Per-resource examples (resources/). One concise XExample per resource (Utilities, Stocks,
    Options, Funds, Markets) showing the first calls you'd write, plus an XAdvancedExample each for
    the less common surface — universal params, date windows, column projection, CSV output, sealed
    chain filters. All run against the live API.
  • Cross-cutting examples (common/), covered once rather than repeated per resource:
    SyncVsAsyncExample (live), ConcurrentRequestsExample (the 50-permit concurrency cap),
    RetryAndBackoffExample (auto retry + Retry-After), ErrorHandlingExample (the sealed
    MarketDataException hierarchy), ConfigurationExample (cascade, redaction, fail-fast — offline),
    ResponseFormatsExample (the response wrapper surface).
  • Kotlin quickstart (src/main/kotlin/.../Quickstart.kt) — the same SDK from Kotlin, sync +
    async. The examples module gains the kotlin("jvm") plugin; the SDK artifact stays Java-only
    (ADR-001 is untouched — this is a consumer module, not the published JAR).
  • MockServer teaching aid — trimmed from the 235-line MockServerControl (dropped the
    Stats/assert framing). It exists only so the three behavior examples are runnable without a paid
    token, and is explicitly not part of the SDK.
  • Removed: the 14 old *App classes + Console + MockServerControl. Rewrote
    build.gradle.kts (16 run tasks under the examples group), the root Makefile (example-*
    targets), and the module README.md as an index/guide.

Design principles

  • Examples teach, they don't test — no assertions. The external-verification role is dropped on
    purpose; that's what the unit/integration suites are for.
  • The mock server is a didactic aid, kept only for behavior that's invisible against the live API
    (concurrency, retry, error types). Resource examples run live.
  • Cross-cutting topics live once in common/, not duplicated across resources.
  • Edge cases that required doctoring a response (Option A → ParseError, strict-default) were
    dropped from the examples — those were contract tests, not teaching.

Verification

Every example was run and its output checked — not just compiled.

  • 12 live (token from examples/consumer-test/.env): all resource examples + advanced variants +
    sync/async + response formats + the Kotlin quickstart returned real market data (e.g. AAPL candles,
    a 5-call option chain with greeks, the exchange calendar correctly flagging the Juneteenth
    holiday).
  • 3 mock (FastAPI server): concurrency observed peak in-flight = 50 exactly; retry recovered
    503→503→200 in ~3 s and honored Retry-After: 3; error handling routed the sealed hierarchy and
    printed the support-info dump.
  • 4 issues found by reading the real output and fixed before commit: limit() doesn't trim
    candles (the count contradicted the label); CSV date columns rendered raw unix epochs (added
    dateFormat → readable dates, also confirming it composes with the asCsv() facet); a
    RateLimitError.getRetryAfter() printed as Optional[PT5S] (unwrapped to 5s).
  • ./gradlew build green (Java + Kotlin).

SDK impact

None. This PR touches only examples/, the root Makefile, and the examples README. No src/
changes, no effect on the published artifact.

Commit

Hash Summary
be8cda6 improve examples

@MarketDataDev03 MarketDataDev03 self-assigned this Jun 23, 2026
@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

The author of this PR, MarketDataDev03, is not an activated member of this organization on Codecov.
Please activate this user on Codecov to display this PR comment.
Coverage data is still being uploaded to Codecov.io for purposes of overall coverage calculations.
Please don't hesitate to email us at support@codecov.io with any questions.

@MarketDataDev03 MarketDataDev03 marked this pull request as ready for review June 24, 2026 12:59
*/
fun main() {
// `use {}` closes the client when the block ends — the Kotlin equivalent of try-with-resources.
MarketDataClient().use { client ->

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The no-arg MarketDataClient() constructor runs with validateOnStartup=true and fires a real /user/ probe — so with a present-but-invalid/expired token it throws AuthenticationError here, before .use {} is entered. That means the catch (e: AuthenticationError) inside the lambda never fires, and the example dies with an uncaught stack trace instead of printing the friendly "Set MARKETDATA_TOKEN" hint.

The Java examples avoid this because try (MarketDataClient client = new MarketDataClient()) puts construction inside the try-with-resources, so their identical catch fires. Of all the examples, the Kotlin interop showcase is the one that crashes ugly on the most common misconfiguration — and the repo's own .env may carry a stale dev token.

Suggest wrapping construction inside the try so the catch covers it:

try {
    MarketDataClient().use { client ->
        val quote = client.stocks().quote(StockQuoteRequest.of("AAPL")).values()[0]
        println("Sync:  ${quote.symbol()} last=${quote.last()}")
        client.stocks()
            .quoteAsync(StockQuoteRequest.of("AAPL"))
            .thenAccept { resp -> println("Async: ${resp.values()[0].last()}") }
            .join()
    }
} catch (e: AuthenticationError) {
    println("Set MARKETDATA_TOKEN (env var or .env) to run this example.")
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, i'm going to fix it

Base automatically changed from 14_code_ajustment to main June 26, 2026 21:48
@MarketDataDev03 MarketDataDev03 merged commit 5c9c587 into main Jun 26, 2026
5 checks passed
@MarketDataDev03 MarketDataDev03 deleted the 15_improve_examples branch June 26, 2026 21:49
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.

2 participants