API Reference overview
The API reference documents the public surface a component developer builds against: the runtime object you construct at startup, the typed accessors that reach each subsystem, and the per-subsystem types (builders, services, models). It is verified against source — Java is the canonical reference, and the other three SDKs mirror it deliberately.
How the reference is organized
Section titled “How the reference is organized”There is one reference page per subsystem, and every page presents all four languages in synced tabs (Java, then Python, then Rust, then TypeScript — in that order). When you switch a tab on one page, the choice follows you across the site, so you read the reference in your language.
The conceptual guides explain why and when to use a subsystem; the reference pages give the exact what — signatures, return types, and per-language naming.
The accessor-name map
Section titled “The accessor-name map”Everything starts from one object: the GGCommons runtime (GgCommons in Rust). You build it
once from the standard CLI args, then call typed accessors on it to reach each subsystem. The
concept is identical in all four languages; only the name differs, following each language’s
convention (Java getX(), Python get_x(), Rust/TS x()).
This table is the map. Find the row for what you need, read across to your language.
| Concern | Java | Python | Rust | TypeScript |
|---|---|---|---|---|
| Build | GGCommonsBuilder.create(name).withArgs(args).build() |
GGCommonsBuilder.create(name).with_args(args).build() |
GgCommonsBuilder::new(name).args(argv).build().await |
new GGCommonsBuilder(name).args(argv).build() (await) |
| Runtime type | GGCommons |
GGCommons |
GgCommons |
GGCommons |
| Messaging | getMessaging() |
get_messaging() |
messaging() |
messaging() |
| Metrics | getMetrics() |
get_metrics() |
metrics() |
metrics() |
| Config | getConfigManager() |
get_config_manager() |
config() |
config() |
| Credentials (opt-in) | getCredentials() |
get_credentials() |
credentials() |
credentials() |
| Parameters (opt-in) | getParameters() |
get_parameters() |
parameters() |
parameters() |
| Streams (opt-in) | getStreams() |
get_streams() |
streams() |
streams() |
| Shutdown | shutdown() |
shutdown() (or a with block) |
none — RAII Drop |
close() (async) |
The opt-in return contract
Section titled “The opt-in return contract”The three newer subsystems — credentials, parameters, streams — are opt-in. Their accessor returns an “absent” value unless the matching config section is present. Everything else (messaging, metrics, config) is always wired and always returns a usable service.
The idea is the same everywhere (“absent when not configured”), but the type follows each language’s idiom:
| Accessor | Java | Python | Rust | TypeScript |
|---|---|---|---|---|
credentials |
null |
None |
Option → None |
undefined |
parameters |
null |
None |
Option → None |
undefined |
streams |
null |
None |
not Option — an empty service |
undefined |
Two language-specific traps:
- Rust
streams()is not anOption. It always returns anArc<dyn StreamService>; when nostreamingsection exists, that service is simply empty. Checkstreams().stream_names()rather than testing forNone. (Credentials and parameters areOption<Arc<dyn ...>>.) - Rust opt-ins are also cargo-feature-gated. The
streams(),credentials(), andparameters()methods only exist when the matching feature (streaming,credentials,parameters) is compiled in — they are off by default. In the other three SDKs the accessor always exists and returns the null/None/undefinedvalue above.
How to read the signatures
Section titled “How to read the signatures”Each reference page shows the real, idiomatic signature for every language. A few conventions repay knowing before you read them:
- Accessor naming is mechanical: Java
getMessaging()⇄ Pythonget_messaging()⇄ Rust/TSmessaging(). Once you know the concern, the name is predictable in each language. build()is async in Rust and TypeScript (await), synchronous in Java and Python.- The argv you pass to the builder differs. Rust
.args(...)expects the full argv including the program name (e.g.std::env::args_os()). TypeScript.args(...)expects argv without the node/script prefix (process.argv.slice(2)). JavawithArgs(...)and Pythonwith_args(...)take the already-stripped application args. - You do not wire your own signal handler. The library installs the SIGTERM/SIGINT handling for
you (Java: a JVM shutdown hook on both signals; TypeScript: SIGTERM + SIGINT; Python: SIGTERM
only; Rust: a watcher that flips readiness to “shutting down” and relies on
Dropfor teardown). Registering another handler just double-runs teardown.shutdown()/close()are idempotent, so calling them explicitly is still safe.
Minimal example
Section titled “Minimal example”The same shape in every language: build the runtime from CLI args, take the accessors you need, run
your business logic, then let the runtime tear down. (messaging() here is the always-present
transport accessor; the opt-ins are reached the same way when their config section is present.)
import com.mbreissi.ggcommons.GGCommons;import com.mbreissi.ggcommons.GGCommonsBuilder;
GGCommons gg = GGCommonsBuilder.create("com.example.MyComponent") .withArgs(args) // already-stripped application args .build();
var config = gg.getConfigManager();var messaging = gg.getMessaging();var metrics = gg.getMetrics();
// ... business logic ...// Do NOT register your own shutdown hook — the library wires SIGTERM/SIGINT itself.// gg.shutdown(); // idempotent; safe to call explicitlyimport sys
from ggcommons.ggcommons_builder import GGCommonsBuilder
gg = (GGCommonsBuilder.create("com.example.MyComponent") .with_args(sys.argv[1:]) # already-stripped application args .build())
config = gg.get_config_manager()messaging = gg.get_messaging() # the MessagingClient class (static handle)metrics = gg.get_metrics() # the MetricEmitter class (static handle)
# ... business logic ...gg.shutdown() # or: with GGCommonsBuilder.create(...).build() as gg:use ggcommons::prelude::*;
#[tokio::main]async fn main() -> anyhow::Result<()> { let gg = GgCommonsBuilder::new("com.example.MyComponent") .args(std::env::args_os()) // argv INCLUDES the program name .build() .await?;
let cfg = gg.config(); // atomic config snapshot if let Ok(messaging) = gg.messaging() { // Result, not Option let _ = messaging; }
// ... business logic ... Ok(()) // dropping `gg` releases all resources (RAII) — there is no close()}import { GGCommonsBuilder } from "@mbreissi/ggcommons";
const gg = await new GGCommonsBuilder("com.example.MyComponent") .args(process.argv.slice(2)) // argv WITHOUT the node/script prefix .build();
const config = gg.config();const messaging = gg.messaging(); // throws if no transport is wiredconst metrics = gg.metrics();
// ... business logic ...await gg.close(); // idempotent