VOOZH about

URL: https://deepwiki.com/hypervel/api-client/8-advanced-topics

⇱ Advanced Topics | hypervel/api-client | DeepWiki


Loading...
Menu

Advanced Topics

This section documents advanced patterns and implementation details in the hypervel/api-client package. These patterns enable extensibility and maintainability through sophisticated PHP techniques.

The advanced patterns covered in this section are:

  • Context Management (Section 8.1) - Metadata propagation using the HasContext trait
  • Fluent Interface Patterns (Section 8.2) - Method chaining for configuration
  • Magic Method Delegation (Section 8.3) - Transparent method forwarding via __call()

Additional advanced topics covered on this page include middleware caching and generic type safety.

For basic usage, see Quick Start. For middleware configuration, see Middleware System.


Core Pattern Overview

The API client employs three core patterns that work together:

PatternPurposePrimary LocationDetails
Context ManagementPropagate metadata through lifecycleHasContext traitSection 8.1
Fluent InterfaceEnable method chainingConfiguration methods returning staticSection 8.2
Magic DelegationForward methods between layers__call() in ApiClient and PendingRequestSection 8.3

These patterns create a developer-friendly API while maintaining type safety and extensibility.

Sources: src/HasContext.php1-38 src/ApiClient.php1-116 src/PendingRequest.php1-342


Pattern Integration

The three core patterns work together throughout the request lifecycle:


Integration Points:

PhasePattern UsedImplementation Location
ConfigurationMagic Delegationsrc/ApiClient.php40-45
ConfigurationFluent Interfacesrc/PendingRequest.php67-142
Request ProcessingContext Systemsrc/PendingRequest.php293-299
Response ProcessingContext Systemsrc/PendingRequest.php301-307

Sources: src/ApiClient.php40-45 src/PendingRequest.php67-142 src/PendingRequest.php293-307


Context System Architecture

The context system provides a mechanism for attaching arbitrary metadata to request and response objects, enabling data to flow through the entire request lifecycle without polluting method signatures.

Context Implementation


Sources: src/HasContext.php1-38 src/PendingRequest.php293-307

Context Data Flow

The context system operates through a simple key-value store attached to each request and response object:


Sources: src/PendingRequest.php293-307 src/HasContext.php8-37

Context Storage Mechanism

The HasContext trait implements a simple array-based storage system:

MethodSignaturePurpose
withContext()withContext(string|array $key, mixed $value = null): staticSet single key-value pair or merge array of context data
context()context(?string $key = null): mixedRetrieve specific key or entire context array

The implementation at src/HasContext.php8-37 uses a protected $context property to store data. The withContext() method supports both single key-value pairs and bulk array merging, returning static to enable method chaining.

Key Implementation Details:

  • Array Merge Support: src/HasContext.php16-19 - When an array is passed as the first argument, it merges with existing context
  • Null Key Retrieval: src/HasContext.php32-34 - Calling context() without arguments returns the entire context array
  • Safe Key Access: src/HasContext.php33 - Returns null for non-existent keys rather than throwing errors

Sources: src/HasContext.php8-37


Fluent Interface Pattern

The fluent interface pattern enables readable, chainable configuration by ensuring configuration methods return static rather than void. This pattern is used extensively throughout PendingRequest and ApiClient.

Fluent Method Chain Example


Sources: src/PendingRequest.php150-167 src/PendingRequest.php87-92 src/PendingRequest.php117-122

Configuration Method Pattern

All configuration methods in PendingRequest follow a consistent pattern:


Sources: src/PendingRequest.php67-142

Fluent Methods Catalog

The following table catalogs all fluent configuration methods in PendingRequest:

MethodLinesModifies PropertyValidation
enableMiddleware()src/PendingRequest.php67-72$enableMiddlewareNone
disableMiddleware()src/PendingRequest.php77-82$enableMiddlewareNone
withMiddlewareOptions()src/PendingRequest.php87-92$middlewareOptionsNone
withGuzzleOptions()src/PendingRequest.php97-102$guzzleOptionsNone
withRequestMiddleware()src/PendingRequest.php107-112$requestMiddlewareNone
withAddedRequestMiddleware()src/PendingRequest.php117-122$requestMiddlewareNone
withResponseMiddleware()src/PendingRequest.php127-132$responseMiddlewareNone
withAddedResponseMiddleware()src/PendingRequest.php137-142$responseMiddlewareNone
withResource()src/PendingRequest.php150-167$resourceClass existence and inheritance

Sources: src/PendingRequest.php67-167

Immutability vs Mutability

The fluent interface in this package uses mutable objects rather than immutability:

  • Configuration methods modify the instance in-place and return $this
  • This differs from true immutability patterns where each method returns a new instance
  • The mutable approach is more memory-efficient and appropriate for request builders that are typically not reused

The pattern can be identified at src/PendingRequest.php69-71 where $this->enableMiddleware = true modifies the instance directly before returning $this.

Sources: src/PendingRequest.php67-142


Magic Method Delegation System

The API client uses PHP's __call() magic method to create transparent delegation chains, enabling seamless method forwarding between components.

Delegation Chain Architecture


Sources: src/ApiClient.php40-45 src/PendingRequest.php257-263

Two-Level Delegation

The system implements delegation at two distinct levels:

Level 1: ApiClient to PendingRequest

At src/ApiClient.php40-45 the ApiClient::__call() method forwards all undefined method calls to a fresh PendingRequest instance:

Implementation Pattern:

  1. Consumer calls method on ApiClient that doesn't exist
  2. PHP invokes __call($method, $parameters)
  3. __call() obtains PendingRequest via getClient()
  4. Method is invoked on PendingRequest with original parameters
  5. Result is returned to consumer

This delegation enables calling methods like get(), post(), and configuration methods directly on ApiClient instances.

Sources: src/ApiClient.php40-45 src/ApiClient.php112-115

Level 2: PendingRequest to ClientPendingRequest

At src/PendingRequest.php257-263 the PendingRequest::__call() method forwards HTTP client configuration methods to the underlying hypervel/http-client instance:

Implementation Pattern:

  1. Consumer calls HTTP client method (e.g., withHeaders(), timeout())
  2. PHP invokes __call($method, $parameters)
  3. __call() obtains ClientPendingRequest via getClient()
  4. Method is invoked on HTTP client
  5. PendingRequest returns $this to maintain fluent interface

This delegation provides access to all HTTP client configuration methods without explicitly implementing them.

Sources: src/PendingRequest.php257-263 src/PendingRequest.php328-341

Delegation Flow with Method Resolution


Sources: src/ApiClient.php40-45 src/PendingRequest.php257-263 src/PendingRequest.php265-291

Method Resolution Priority

When a method is called on PendingRequest, PHP resolves it in this order:

PriorityLocationExample Methods
1Direct methods on PendingRequestget(), post(), withResource(), enableMiddleware()
2Conditionable trait methodswhen(), unless()
3__call() delegation to HTTP clientwithHeaders(), timeout(), retry()

The delegation only occurs when methods don't exist on the class itself, as seen at src/PendingRequest.php257-263

Sources: src/PendingRequest.php1-342 src/PendingRequest.php24

Return Type Handling

The delegation system carefully manages return types to maintain the fluent interface:

  • ApiClient::__call() at src/ApiClient.php41 declares return type as mixed, allowing it to return whatever PendingRequest methods return (typically ApiResource or PendingRequest)
  • PendingRequest::__call() at src/PendingRequest.php257 declares return type as static, always returning $this regardless of what the HTTP client returns
  • This ensures that PendingRequest configuration chains remain unbroken

Sources: src/ApiClient.php40-45 src/PendingRequest.php257-263


Pattern Integration Example

The three advanced patterns work together synergistically:


Sources: src/ApiClient.php40-45 src/PendingRequest.php67-142 src/PendingRequest.php293-307

Integration Points

PatternUsage PointBenefit
Magic Delegationsrc/ApiClient.php40-45Enables calling HTTP methods directly on ApiClient
Fluent Interfacesrc/PendingRequest.php67-142Configuration methods chain seamlessly
Context Systemsrc/PendingRequest.php293-307Middleware options propagate through lifecycle
All ThreeRequest execution flowClean API with powerful extensibility

Sources: src/ApiClient.php1-116 src/PendingRequest.php1-342 src/HasContext.php1-38


Middleware Caching Strategy

The API client implements a static middleware cache to optimize performance when the same middleware classes are used repeatedly.

Cache Implementation


Sources: src/PendingRequest.php309-326

Cache Characteristics

The caching implementation at src/PendingRequest.php51 and src/PendingRequest.php309-326 exhibits these properties:

PropertyValueImplication
ScopeStatic (class-level)Shared across all PendingRequest instances
KeyMiddleware class name (string)One instance per middleware class
InitializationLazy (on first use)No overhead until middleware is needed
LifetimeUntil flushCache() calledPersists across requests in long-running processes
Constructor Args$this->client->getConfig()Config object passed during instantiation

Cache Flush Method: The cache can be cleared via flushCache() at src/PendingRequest.php249-252 which resets static::$cachedMiddleware to an empty array.

Sources: src/PendingRequest.php51 src/PendingRequest.php309-326 src/PendingRequest.php249-252

Cache Benefits and Tradeoffs

Benefits:

  • Eliminates repeated middleware instantiation overhead
  • Reduces memory allocation in high-throughput scenarios
  • Middleware constructors execute only once per class

Tradeoffs:

  • Middleware instances are shared across all requests
  • Middleware must be stateless or carefully manage internal state
  • Long-running processes accumulate cached instances
  • Configuration changes require cache flush

The implementation at src/PendingRequest.php322 shows that each middleware receives the ApiClient's configuration object during construction, ensuring middleware can access configuration even when cached.

Sources: src/PendingRequest.php309-326


Generic Type Safety System

The API client uses PHP's generic type system (via PHPDoc annotations) to maintain type safety across the request/response lifecycle.

Type Parameter Flow


Sources: src/ApiClient.php9-13 src/PendingRequest.php18-29

Type Parameter Constraints

The generic type system enforces constraints at multiple levels:

ComponentType ParametersConstraintsLocation
ApiClientTConfigMust extend DataObjectsrc/ApiClient.php10
ApiClientTResourceMust extend ApiResourcesrc/ApiClient.php11
PendingRequestTResourceMust extend ApiResourcesrc/PendingRequest.php19
withResource()ParameterRuntime validation via is_subclass_of()src/PendingRequest.php150-167

Runtime Validation: The withResource() method at src/PendingRequest.php150-167 performs runtime validation to ensure type safety:

  1. Class Existence Check at src/PendingRequest.php152-156: Throws InvalidArgumentException if class doesn't exist
  2. Inheritance Check at src/PendingRequest.php158-162: Throws InvalidArgumentException if class doesn't extend ApiResource

Sources: src/ApiClient.php9-13 src/PendingRequest.php18-29 src/PendingRequest.php150-167

Type Propagation Through Methods

HTTP methods in PendingRequest declare their return type using the TResource generic:


Sources: src/PendingRequest.php175-244 src/PendingRequest.php265-291

At src/PendingRequest.php290 the sendRequest() method creates the resource using $this->resource::make(), where $this->resource contains the class string of type TResource (set at src/PendingRequest.php29).

Sources: src/PendingRequest.php175-244 src/PendingRequest.php265-291


Summary

The advanced patterns in hypervel/api-client work cohesively to provide:

  • Context System: Metadata propagation without polluting method signatures
  • Fluent Interface: Readable, chainable configuration
  • Magic Delegation: Transparent method forwarding between layers
  • Middleware Caching: Performance optimization through instance reuse
  • Generic Types: Compile-time type safety with runtime validation

These patterns enable the package to provide a clean, type-safe API while remaining extensible and maintainable. For implementation details on specific subsystems, see:

Sources: src/ApiClient.php1-116 src/PendingRequest.php1-342 src/HasContext.php1-38