Client architecture¶
The SDK has four layers.
1. Configuration¶
Configuration owns the deployment base URL, bearer credential, timeout, user-agent, and retry policy. It contains no organization identifier. Organization scope remains a property of the credential and of route parameters.
2. Request executor¶
RequestExecutor converts an API service call into a PSR-7 request, adds bearer authentication and JSON headers, sends the request through PSR-18, applies the retry policy, decodes JSON, and maps error statuses to exceptions.
The low-level transport rejects absolute request paths to prevent a caller-supplied path from redirecting the configured credential to another host.
3. API services¶
Service classes are thin route mappings:
OrganizationsApiProjectsApiBoardsApiTicketsApiDocumentsApiNotificationsApi
They construct route paths, query parameters, and request bodies. They do not contain persistence, caching, or background behavior.
4. Requests, responses, and models¶
Create request classes are immutable value objects. PATCH request classes are clone-based builders where an omitted property and an explicit JSON null remain different.
All API methods return ApiResponse. Models such as Project, Board, Ticket, and Document are optional hydration helpers for OpenAPI component schemas.
Dependency direction¶
Your application
|
v
OkatanaClient
|
+--> API service
| |
| +--> request DTO / query DTO
|
+--> RequestExecutor
|
+--> PSR-17 factories
+--> PSR-18 client
+--> RetryPolicy
+--> PSR-3 logger
|
+--> ApiResponse / exceptions
Why PSR-18¶
The SDK does not force a specific HTTP stack. Guzzle is included as a default, but the core executor depends on PSR client and message abstractions. This maintains compatibility with applications standardizing on other implementations.