diff --git a/docs/knowledge/README.md b/docs/knowledge/README.md index b05ca895ace..d90abef9427 100644 --- a/docs/knowledge/README.md +++ b/docs/knowledge/README.md @@ -15,7 +15,7 @@ is the signal. |------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------| | [build.md](build.md) | Always — build requirements and common tasks | | [general-patterns.md](general-patterns.md) | Always — style, nullability, visibility, AutoValue, locking, logging, internal & impl packages | -| [api-design.md](api-design.md) | Public API additions, removals, renames, or deprecations or implementations; configuration changes; null guards; stable vs alpha compatibility | +| [api-design.md](api-design.md) | Public API additions, removals, renames, or deprecations or implementations; configuration changes; convenience APIs; null guards; stable vs alpha compatibility | | [gradle-conventions.md](gradle-conventions.md) | `build.gradle.kts` or `settings.gradle.kts` changes; new modules | | [testing-patterns.md](testing-patterns.md) | Test files in scope — assertions, test utilities, test suites | | [other-tasks.md](other-tasks.md) | Dev environment setup, benchmarks, composite builds, native image tests, OTLP protobuf updates | diff --git a/docs/knowledge/api-design.md b/docs/knowledge/api-design.md index fd63bd8ec54..6432d621fee 100644 --- a/docs/knowledge/api-design.md +++ b/docs/knowledge/api-design.md @@ -76,6 +76,66 @@ Follow specification-defined semantics. Relaxing an API to accept a previously rejected `0` is allowed, including in stable modules. Document and test zero behavior explicitly. +## Convenience APIs + +Prefer a small, composable API. When in doubt, leave convenience APIs out and +add them when demand demonstrates their value. + +### Bounded surface + +Do not provide every combination of optional arguments or configuration values. +Prefer builders or options objects as combinations grow. + +For example, histogram aggregation options belong in +`ExplicitBucketHistogramOptions`, rather than separate overloads for every +combination of bucket boundaries and min/max recording. + +### Builder shortcuts + +Keep builders as the primary configuration entry point. Shortcuts should be +justified by a concrete benefit, such as avoiding meaningful runtime overhead. +For SDK objects constructed during initialization, shortcuts are rarely +justified. + +For example, prefer `SdkMeterProvider.builder().build()` over adding an +equivalent `SdkMeterProvider.create()`. + +### Common cases + +When an API accepts an expressive abstraction, consider providing convenience +methods, constants, or implementations for common use cases. + +For example, `AggregationTemporalitySelector` supports arbitrary selection by +instrument type, while `deltaPreferred()` and `alwaysCumulative()` provide +common selection policies. + +### Existing patterns + +Follow the [API consistency](general-patterns.md#api-consistency) guidance when +deciding which conveniences to provide. Within an established API, preserve +consistent overload patterns rather than evaluating each method in isolation. + +For example, a new metric instrument should follow the existing recording +overloads for omitted attributes and context. + +### Java representations + +Follow the representations accepted by related APIs before introducing +alternatives. Supporting another representation should address a concrete use +case, not merely an available conversion. + +For example, metric reader duration settings accept both `Duration` and `long` +with `TimeUnit`. Follow that pattern for similar settings. + +### Optional arguments + +Prefer overloads with documented defaults over requiring callers to pass `null` +to omit an argument. This avoids unnecessarily introducing `@Nullable` into the +API. + +For example, `Span.addEvent(String)` uses empty attributes, while +`Span.addEvent(String, Attributes)` accepts explicit attributes. Callers need +not pass `null` to indicate that attributes are absent. ## Deprecating API Applies to both stable and alpha modules. Use plain `@Deprecated` — do **not** use diff --git a/docs/knowledge/general-patterns.md b/docs/knowledge/general-patterns.md index 7d5860d87a4..8ea5bafce05 100644 --- a/docs/knowledge/general-patterns.md +++ b/docs/knowledge/general-patterns.md @@ -14,9 +14,10 @@ For null guard behavior at public API boundaries, see [api-design.md](api-design ## API consistency -The project aims to provide a consistent experience across all public APIs. When designing new -API, look for prior art in the project before introducing new patterns — prefer the style already -established in the same package, then the same module, then the broader project. +The project aims to provide a consistent experience across all public APIs. When +designing new API, look for prior art before introducing new patterns. Give the +most weight to precedent in the same file, then the same package, then similar +APIs in other packages, then the broader project. ## AutoValue