SDK design and language support
1) SDK goals and success criteria
Developer Experience (DX): intuitive APIs, uniform semantics between languages.
Reliability: timeouts/retreats/idempotency out of the box.
Security: secrets, signatures, TLS, compatibility with proksi/企业 environments.
Observability: logs, metrics, traces in standard tools for the language.
Economy: minimum egress/CPU, effective pagination, batches.
Stability: strict semver, backward compatibility, LTS branches.
2) Architectural principles
1. Thin client, strong contracts: SDK wrapper over protocol (REST/gRPC), without hidden business logic.
2. Unified surface: same concepts (Client, Request, Response, Error, Paginator, WebhookVerifier).
3. Safe by default: reasonable timeouts, exponential backoff + jitter, repetition protection.
4. Config layering: ENV → config file → constructor → method parameters.
5. Pluggable transport: HTTP/gRPC is removable, compatible with connection proksi/池.
6. Testability: interfaces/fakes, dependency injection, record-replay.
7. Error I18n: machine'error _ code'is stable; messages are localizable.
8. Accessibility: asynchronous variants (usually 'AsyncClient') where appropriate.
9. Security-first: secrets do not fall into logs, PII edition, FIPS-compatible crypto libraries if necessary.
3) Support table and opportunity parity
4) API base surface (canonical model)
Common entities
Client: configuring transport, keys, retrays, telemetry hooks.
Request/Response: type-safe models/DTO, pagination/cursors.
Error: a single class with'status', 'error _ code ', 'trace _ id', 'retriable '.
Paginator/Iterator: lazy search of pages/cursors.
WebhookVerifier: HMAC/mTLS check, dedup by 'event _ id'.
Mini Example (TypeScript)
ts const client = new GambleHubClient({
apiKey: process. env. GH_API_KEY!,
timeoutMs: 10_000,
retries: { max: 5, strategy: "expo-jitter" }
});
const { items, nextCursor } = await client. reports. list({ from, to, cursor });
for await (const report of client. reports. iter({ from, to })) { /... / }
Mini-example (Python, async)
py from gamblehub import AsyncClient, WebhookVerifier
client = AsyncClient(api_key=API_KEY, timeout=10, retries={"max":5})
async for user in client. users. iter(updated_after=ts):
...
verifier = WebhookVerifier(secret=WEBHOOK_SECRET)
if verifier. verify(headers, body): ack()
5) Configuration and Runtime
ENV: `GH_API_KEY`, `GH_ENDPOINT`, `GH_TIMEOUT_MS`, `HTTP_PROXY/HTTPS_PROXY`, `GH_REGION`.
Constructor-Overrides ENV.
Per-call overrides: method-level timeout/retray.
TLS/mTLS: path to the certificate/key, pinning CA if necessary.
Connection pools: keep-alive, HTTP/2, concurrency constraint.
6) Safety out of the box
Secrets: do not log, hide in stack traces; redaction ``.
Signatures: HMAC for webhooks, 'X-Key-Id '/key rotation, support for "two keys" active/next.
Idempotency: transparent setting of'Idempotency-Key'for write operations (restart is safe).
RBAC/Scopes: convenient enumerations/constants for scopes.
PII policy: standard editing interfaces for logging.
7) Reliability: Timeouts, Retreats, Backs
Default timeout: 10-15s; connection 3-5s.
Retrai: for 5xx/408/429 (respect 'Retry-After'), exponential backoff + jitter, retry/time limit.
Circuit-breaker: optional in the SDK (or third-party lib recommendations).
Idempotent write: automatic repeat by key; collisions → raise '409. IDEMP_REPLAY'
8) Pagination, cursors and streaming
Cursor/iterator: lazy brute force, auto-repeats for transient errors.
Keyset pagination: stable ordering '(updated_at,id)'.
Backpressure: limit of simultaneous requests; в async-SDK — `async for`/`channels`.
Streaming (where available): SSE/WebSocket/gRPC-stream with auto-reconnect and deduplication by 'sequence'.
9) Mistakes and contract
Single hierarchy:- `ApiError` (базовый) → подтипы: `AuthError(401)`, `PermissionError(403)`, `NotFound(404)`, `Conflict(409)`, `RateLimit(429)`, `ValidationError(422)`, `ServerError(5xx)`.
- Свойства: `status`, `error_code`, `message`, `trace_id`, `retriable`, `details`.
- Best practice: messages are human-readable, 'error _ code' is stable.
10) Language idioms
TypeScript/JS
Promise-based + generators for pagination; ESM + CJS packets.
Tree-shaking, minimal polyphiles, abort signals ('AbortController').
Python
Sync + Async (aiohttp/httpx), context managers, 'pydantic' models (or dataclasses).
Wheels для linux/macos/windows; proxies/NO_PROXY support.
Java
'CompleteFuture '(if necessary),' AutoCloseable ',' Duration ',' Executor '.
HTTP client: `java. net. http 'or OkHttp; SLF4J for logs.
Go
Contexts' context. Context`, `http. Client'with tuned Transport, interfaces for tests.
Error wrapping (`fmt. Errorf ("% w," err) '), sentinel semantics of errors.
.NET
`HttpClientFactory`, `CancellationToken`, `IAsyncEnumerable<T>`.
Polly policies (retry/circuit-breaker).
... etc. for PHP/Ruby (PSR-18, Faraday/Net:: HTTP).
11) Logging, metrics, tracing
Logs: levels (ERROR/WARN/INFO/DEBUG), correlation 'trace _ id', disabling sensitive data.
Метрики: `requests_total`, `errors_total{status}`, `retry_count`, `latency_ms`, `throttled_total`.
Traces: OpenTelemetry hooks (span to API call, endpoint, status, retry attributes).
Debug-mode: environment variable'GH _ SDK _ DEBUG = 1 '- printing HTTP headers (without secrets) and times.
12) Documentation and examples
Quickstart 5 minutes: auth, first request, pagination, 429 processing.
Cookbook: webhooks (signature verification), idempotent write, replay.
API reference: Autogen from OpenAPI/Protobuf, but with "manual" examples.
Snippets: ready-made pieces of code for popular tasks (Python/TS/Java/Go/.NET).
13) Generation vs manual coding
Combined approach: codegen (models/clients) + manual "pens" for ergonomics/idempotency/paginators.
Templates: uniform method names ('create/get/list/update/delete'), stab. signatures.
Checking "diff-compatibility" after regen (CI-gate).
14) Versioning, compatibility and deprections
SemVer: X.Y.Z. Breaking - major only.
Stability policy: minor releases - add fields/methods, do not change contracts.
Deprecation: annotations/attributes @ Deprecated/Obsolete, runtime warnings once per process, window ≥ 90 days.
LTS branches: backport of critfixes (no new features).
15) Releases and Supply Chain
CI/CD: linters/formatters, unit + integration, contract tests, e2e vs. sandbox.
Artifact signature: Sigstore/GPG, checksums on releases.
Publication: npm/PyPI/Maven/NuGet/Go/Composer/RubyGems with changelog and release notes.
SemVer gate: auto-checking the compatibility of the public API (for example, 'apiregistry diff').
16) Testing (quality matrix)
Unit: models, serialization, validation, retrays/timeouts.
Contract: against OpenAPI/Protobuf schemes (negative/edge cases).
Integration: vs. sandbox (idempotency, 429/5xx, webhooks).
Load/soak: pagination/stream, backpressure.
Fuzz: fields/headers/time boundaries.
Compat - old SDKs ↔ new APIs and vice versa.
Smoke-pack: 5 minutes to catch a regression in CI.
17) Telemetry and privacy policies
Optional-opt-in: collection of aggregated SDK metrics (version, language, statuses) without PII.
Config: 'telemetry: off' anonymous' full '(default is off/anonymous).
Transparency: Document what's going to happen and why; let's check the disconnect box.
18) Performance and FinOps
Batching: combine small queries; limit RPS; gzip/br.
ETag/If-None-Match caching, conditional GET.
Economical models: lazy iterators instead of loading everything into memory.
Concurrency with limit: 'max _ concurrency' so as not to "DDOS" the API.
19) Typical SDK components (skeletons)
Error (TypeScript)
ts export class ApiError extends Error {
constructor(
readonly status: number,
readonly errorCode: string,
readonly traceId?: string,
readonly retriable?: boolean,
readonly details?: unknown
) { super(`${status} ${errorCode}`); }
}
Paginator (Python)
py class Paginator(Generic[T]):
def __init__(self, fetch_page):
self._fetch = fetch_page self._cursor = None async def __aiter__(self):
while True:
page = await self._fetch(self._cursor)
for item in page. items:
yield item if not page. has_more: break self._cursor = page. next_cursor
WebhookVerifier (Go)
go func Verify(body []byte, signatureHeader, secret string) bool {
parts:= strings. SplitN(signatureHeader, "=", 2)
mac:= hmac. New(sha256. New, []byte(secret))
mac. Write(body)
expected:= base64. StdEncoding. EncodeToString(mac. Sum(nil))
return hmac. Equal([]byte(parts[1]), []byte(expected))
}
20) Support, SLA and Community
SLA by SDK: critical bugs - fix ETA, communication channels, compatibility matrix (SDK↔API).
Issue templates: bug/feature/question, auto-triage by language/version.
Roadmap/labels: «good first issue», «help wanted».
Security policy: `SECURITY. md ', channel for reporting vulnerabilities, CVE if necessary.
21) SDK Quality Checklist
- Single model error ('status', 'error _ code', 'trace _ id', 'retriable').
- Timeouts/retreats/jitter, respect for'Retry-After'.
- Idempotency write, automatic'Idempotency-Key '.
- Cursor pagination, lazy iterators/streams.
- WebhookVerifier with HMAC/mTLS and deduplication.
- Configuration via ENV/constructor/parameters.
- Logging/metrics/OTel hooks, debug mode without secrets.
- SemVer, decrements of ≥90 days, LTS branches.
- Complete examples and Cookbook on popular tasks.
- Feature parity matrix between languages in CI.
22) Implementation plan (3 iterations)
1. MVP (2-3 weeks): basic Client, auth, 3-5 key endpoints, pagination, single error-model, retrai/timeouts; TS+Python.
2. Scale (3-5 weeks): Java/Go/.NET, WebhookVerifier, idempotency write, telemetry hooks, generating models from OpenAPI.
3. Pro (continuous): streaming/SSE/gRPC, perf optimizations, LTS branches, extended Cookbook, migration/decrement tools.
23) Mini-FAQ
Generate everything or write with your hands?
Generate models/clients, and ergonomics (paginators, retrays, idempotency, convenient signatures) - manually.
Do I need a separate async-SDK?
В Python — да (`AsyncClient`); in JS - by default; v.NET/Java - asynchronous calls if possible.
How to keep the parity of languages?
Matrix feature in CI, releases "by belts" (TS→Py→Java→Go→.NET) with auto-report "that lags behind."
Total
A strong SDK is a single surface, reliable defaults and predictable contracts that are the same in all languages. Give developers safe settings out of the box, an understandable error-model, convenient pagination and verification of webhooks, complete this with high-quality documentation and strict semver. Then the integrations will be fast, the support cheap, and the ecosystem sustainable and scalable.