forked from apoloz/alfa-bank-sdk
refactor(core): enhance SDK structure and documentation
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
130
src/Core/AlfaBankConnector.php
Normal file
130
src/Core/AlfaBankConnector.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/*
|
||||
// MODULE_CONTRACT: Defines the primary transport layer for the Alfa Bank BaaS API.
|
||||
// RESPONSIBILITY: To manage mTLS configuration, authentication state, retries, and middleware for all BaaS API interactions.
|
||||
// INPUTS: AlfaConfig (DTO), SignerInterface (service).
|
||||
// OUTPUTS: An authenticated Saloon Connector instance capable of sending requests.
|
||||
// NOTES:
|
||||
// - Supports separate keys for Transport (mTLS) and Signing (JWS/CMS).
|
||||
// - Uses `login` method for OAuth 2.0 Client Credentials flow.
|
||||
// - Compatible with Saloon v3.
|
||||
// LINKS: AlfaBankServiceProvider.php#bind_connector
|
||||
*/
|
||||
|
||||
namespace Apoloz\AlfaBank\Core;
|
||||
|
||||
// <SECTION name="module_imports" intent="Import necessary contracts, services, and base framework components for the connector's operation.">
|
||||
// <BELIEF_STATE "Saloon's plugin architecture requires importing traits for features like retries and timeouts. Local contracts (SignerInterface) are imported for dependency injection.">
|
||||
use Apoloz\AlfaBank\Contracts\SignerInterface;
|
||||
use Apoloz\AlfaBank\Http\Middleware\AlfaResponseMiddleware;
|
||||
use Apoloz\AlfaBank\Http\Middleware\RequestIdMiddleware;
|
||||
use Apoloz\AlfaBank\Http\Pagination\AlfaOffsetPaginator;
|
||||
use Apoloz\AlfaBank\Requests\Auth\GetTokenRequest;
|
||||
use Saloon\Http\Connector;
|
||||
use Saloon\Http\Request;
|
||||
use Saloon\PaginationPlugin\Contracts\HasPagination;
|
||||
use Saloon\PaginationPlugin\OffsetPaginator;
|
||||
use Saloon\Traits\RequestProperties\HasTries;
|
||||
use Saloon\Traits\Plugins\HasTimeout;
|
||||
|
||||
class AlfaBankConnector extends Connector implements HasPagination
|
||||
{
|
||||
use HasTimeout;
|
||||
use HasTries;
|
||||
|
||||
public function __construct(
|
||||
protected AlfaConfig $alfaConfig,
|
||||
protected ?SignerInterface $signer = null
|
||||
) {
|
||||
$this->tries = 3;
|
||||
$this->retryInterval = 500;
|
||||
}
|
||||
|
||||
public function resolveBaseUrl(): string
|
||||
{
|
||||
return $this->alfaConfig->baseUrl;
|
||||
}
|
||||
|
||||
protected function defaultConfig(): array
|
||||
{
|
||||
$config = [
|
||||
'cert' => $this->alfaConfig->certificatePath,
|
||||
'ssl_key' => $this->alfaConfig->privateKeyPath,
|
||||
'verify' => true,
|
||||
];
|
||||
|
||||
if ($this->alfaConfig->caBundlePath) {
|
||||
$config['verify'] = $this->alfaConfig->caBundlePath;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
protected function defaultMiddleware(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function boot(\Saloon\Http\PendingRequest $pendingRequest): void
|
||||
{
|
||||
$pendingRequest->middleware()->onResponse(new AlfaResponseMiddleware());
|
||||
$pendingRequest->middleware()->onRequest(new RequestIdMiddleware());
|
||||
}
|
||||
|
||||
public function paginate(Request $request): OffsetPaginator
|
||||
{
|
||||
return new AlfaOffsetPaginator($this, $request);
|
||||
}
|
||||
|
||||
public function login(?string $clientId = null, ?string $clientSecret = null): static
|
||||
{
|
||||
// Allow overriding config via method arguments
|
||||
$clientId = $clientId ?? $this->alfaConfig->clientId;
|
||||
$clientSecret = $clientSecret ?? $this->alfaConfig->clientSecret;
|
||||
|
||||
if (!$clientId || !$clientSecret) {
|
||||
throw new \RuntimeException("Client ID/Secret not configured.");
|
||||
}
|
||||
|
||||
$request = new GetTokenRequest(
|
||||
clientId: $clientId,
|
||||
clientSecret: $clientSecret,
|
||||
grantType: 'client_credentials'
|
||||
);
|
||||
|
||||
// Send request (using self to reuse cert/ssl config)
|
||||
// We temporarily disable auth middleware if we had any,
|
||||
// but here we are raw, so it's fine.
|
||||
$response = $this->send($request);
|
||||
$data = $response->dto();
|
||||
|
||||
$this->authenticate(new \Saloon\Http\Auth\TokenAuthenticator($data->access_token));
|
||||
|
||||
return $this;
|
||||
}
|
||||
// </SECTION>
|
||||
|
||||
// <SECTION name="signer_accessor" intent="Provide access to the configured signing service for requests that require a digital signature.">
|
||||
// <BELIEF_STATE "Requests should not instantiate their own signing logic. The connector acts as a service locator, providing the globally-configured Signer service. This ensures that all signatures are generated consistently.">
|
||||
public function getSigner(): SignerInterface
|
||||
{
|
||||
if (!$this->signer) {
|
||||
throw new \RuntimeException("No signer configured for this connector.");
|
||||
}
|
||||
return $this->signer;
|
||||
}
|
||||
// </SECTION>
|
||||
|
||||
// <SECTION name="logging_mutator" intent="Allow attaching a PSR-3 logger to the connector for debugging.">
|
||||
// <BELIEF_STATE "Logging should be an optional, opt-in feature. This method provides a fluent interface to attach a logging middleware, which will automatically sanitize sensitive data before output.">
|
||||
public function withLogging(\Psr\Log\LoggerInterface $logger): static
|
||||
{
|
||||
$middleware = new \Apoloz\AlfaBank\Http\Middleware\LoggingMiddleware($logger);
|
||||
|
||||
$this->middleware()->onRequest([$middleware, 'onRequest']);
|
||||
$this->middleware()->onResponse([$middleware, 'onResponse']);
|
||||
|
||||
return $this;
|
||||
}
|
||||
// </SECTION>
|
||||
}
|
||||
Reference in New Issue
Block a user