stoyantodorov / laravel-api-client
Laravel 的 API 客户端
Requires
- php: ^8.2
- illuminate/contracts: ^10.0||^11.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^9.0.0||^8.22.0
- pestphp/pest: ^2.34
- pestphp/pest-plugin-arch: ^2.7
- pestphp/pest-plugin-laravel: ^2.3
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3
- spatie/laravel-ray: ^1.35
This package is auto-updated.
Last update: 2024-09-15 14:37:46 UTC
README
此包提供了一种使用 Laravel HTTP 门面进行错误处理、日志记录和事件触发的方法。还有一个令牌服务,可以根据存储的配置或接收到的参数请求访问令牌。
安装
composer require stoyantodorov/laravel-api-client
使用
HttpClient 服务
以符合您需求的方式解析 HttpClient 实例,例如
use Stoyantodorov\ApiClient\Interfaces\HttpClientInterface; $apiClient = resolve(HttpClientInterface::class);
发送请求
$response = $apiClient->get('https://exmple-host', ['queryParam' => 'value']);
您可以在事先配置 PendingRequest
use Illuminate\Support\Facades\Http; $apiClient->get('https://exmple-host', ['queryParam' => 'value'], Http::withToken($token));
您还可以使用 baseConfig 方法添加基础配置
$apiClien->baseConfig(retries: 3, retryInterval: 3000, timout: 60, connectTimeout: 5, userAgent: 'Test');
此方法可以接收已配置的 PendingRequest
use Illuminate\Support\Facades\Http; $apiClient->baseConfig(retries: 3, pendingRequest: Http::withToken($token));
使用 send 方法发送特定 HTTP 方法和格式
use Stoyantodorov\ApiClient\Enums\HttpMethod; use Stoyantodorov\ApiClient\Enums\HttpRequestFormat; $apiClient->send(HttpMethod::CONNECT, 'https://exmple-host', HttpRequestFormat::QUERY, []);
可选地,您也可以添加已配置的 PendingRequest
use Illuminate\Support\Facades\Http; use Stoyantodorov\ApiClient\Enums\HttpMethod; use Stoyantodorov\ApiClient\Enums\HttpRequestFormat; $apiClient->send(HttpMethod::CONNECT, 'https://exmple-host', HttpRequestFormat::QUERY, [], Http::withToken($token));
当您需要发送请求而不进行错误处理、日志记录和事件触发时,请使用 sendRequest
use Stoyantodorov\ApiClient\Enums\HttpClientRequestMethod; $apiClient->->sendRequest(HttpClientRequestMethod::GET, 'https://exmple-host');
日志记录和事件触发可以通过 config 值进行配置
'events' => [ 'onSuccess' => true, 'onRequestException' => true, 'onConnectionException' => true, ], 'logs' => [ 'onRequestException' => true, 'onConnectionException' => true, ],
这些配置可以通过 HttpClient 设置器进行覆盖
$apiClient->fireEventOnSuccess(false);
令牌服务
工厂
有两个工厂实例化 TokenService。第一个从 config 文件设置配置
use Stoyantodorov\ApiClient\Factories\TokenFromConfigFactory; TokenFromConfigFactory::create();
当您使用此工厂时,应在 api-client.php 中设置相关配置
'tokenConfigurationsBase' => [ 'accessTokenRequest' => [ 'url' => '', 'body' => [], 'headers' => [], 'responseNestedKeys' => ['access_token'], 'method' => 'post', 'dispatchEvent' => true, ], 'refreshTokenRequest' => [ 'url' => '', 'body' => [], 'headers' => [], 'responseNestedKeys' => ['access_token'], 'method' => 'post', 'dispatchEvent' => true, ], 'tokenRequestsRetries' => 3, ],
第二个工厂从数据对象设置配置
use Stoyantodorov\ApiClient\Factories\TokenFromDataFactory; use Stoyantodorov\ApiClient\Data\TokenData; $tokenData new TokenData( url: 'https://example-host/access-token', body: ['username' => 'testValue', 'password' => 'testValue'], ); TokenFromDataFactory::create($tokenData);
当您使用端点刷新令牌时,应指示工厂发送此类配置
TokenFromConfigFactory::create(hasRefreshTokenRequest: true); use Stoyantodorov\ApiClient\Data\RefreshTokenData;
$refreshTokenData = new RefreshTokenData( url: 'https://example-host/refresh-token', body: ['refreshToken' => 'testValue'], ); TokenFromDataFactory::create(tokenData: $tokenData, refreshTokenData: $refreshTokenData);
您可以指示 TokenFromConfigFactory 从其他配置键加载配置
TokenFromConfigFactory::create(configKey: 'anotherApiConfigurations');
如果您已经有了已接收的令牌,可以将其作为可选参数发送给两个工厂
TokenFromConfigFactory::>create(token: 'someValueOrNull'); TokenFromDataFactory::create(token: 'someValueOrNull');
获取令牌
get 方法发送令牌请求
$service->get();
如果服务实例化时已获得令牌,则该方法将返回该令牌而不是发送新的请求。
相同的方法还可以发送请求以刷新令牌
$service->get(refresh: true);
响应中令牌的 JSON 路径应在 config 文件中设置
'responseNestedKeys' => ['data', 'access_token'],
或在 TokenData 和 RefreshTokenData
new TokenData( url: 'https://example-host/access-token', body: ['username' => 'testValue', 'password' => 'testValue'], responseNestedKeys: ['data', 'access_token'], ); new RefreshTokenData( url: 'https://example-host/refresh-token', body: ['refreshToken' => 'testValue'], responseNestedKeys: ['data', 'access_token'], );
当您需要访问响应时,可以订阅默认触发的事件
use Stoyantodorov\ApiClient\Events\AccessTokenObtained; public function handle(AccessTokenObtained $event): void { $response = $vent->response; }
use Stoyantodorov\ApiClient\Events\AccessTokenRefreshed; public function handle(AccessTokenRefreshed $event): void { $response = $vent->response; }
如果您不使用这些事件,可以从 config 文件中禁用它们
'dispatchEvent' => false,
或 TokenData 和 RefreshTokenData
new TokenData( url: 'https://example-host/access-token', body: ['username' => 'testValue', 'password' => 'testValue'], dispatchEvent: false, ); new RefreshTokenData( url: 'https://example-host/refresh-token', body: ['refreshToken' => 'testValue'], dispatchEvent: false, );
API 参考
HttpClientInterface
/** * Base configuration for PendingRequest * When PendingRequest instance isn't received, new one is created * * @param array $headers * @param int $retries * @param int $retryInterval * @param int $timeout * @param int $connectTimeout * @param string|null $userAgent * @param PendingRequest|null $pendingRequest * @return self */ public function baseConfig( array $headers = [], int $retries = 1, int $retryInterval = 1000, int $timeout = 30, int $connectTimeout = 3, string|null $userAgent = null, PendingRequest|null $pendingRequest = null, ): self; /** * Send a request with given HTTP method, url, options HTTP request format * When PendingRequest instance isn't received, new one is created * * @param HttpMethod $httpMethod * @param string $url * @param HttpRequestFormat $format * @param array $options * @param PendingRequest|null $pendingRequest * @return Response|null */ public function send( HttpMethod $httpMethod, string $url, HttpRequestFormat $format, array $options = [], PendingRequest|null $pendingRequest = null ): Response|null; /** * Send HEAD request * When PendingRequest instance isn't received, new one is created * * @param string $url * @param array $parameters * @param PendingRequest|null $pendingRequest * @return Response|null */ public function head(string $url, array $parameters = [], PendingRequest|null $pendingRequest = null): Response|null; /** * Send GET request * When PendingRequest instance isn't received, new one is created * * @param string $url * @param array $parameters * @param PendingRequest|null $pendingRequest * @return Response|null */ public function get(string $url, array $parameters = [], PendingRequest|null $pendingRequest = null): Response|null; /** * Send POST request * When PendingRequest instance isn't received, new one is created * * @param string $url * @param array $body * @param PendingRequest|null $pendingRequest * @return Response|null */ public function post(string $url, array $body = [], PendingRequest|null $pendingRequest = null): Response|null; /** * Send PUT request * When PendingRequest instance isn't received, new one is created * * @param string $url * @param array $body * @param PendingRequest|null $pendingRequest * @return Response|null */ public function put(string $url, array $body = [], PendingRequest|null $pendingRequest = null): Response|null; /** * Send PATCH request * When PendingRequest instance isn't received, new one is created * * @param string $url * @param array $body * @param PendingRequest|null $pendingRequest * @return Response|null */ public function patch(string $url, array $body = [], PendingRequest|null $pendingRequest = null): Response|null; /** * Send DELETE request * When PendingRequest instance isn't received, new one is created * * @param string $url * @param array $body * @param PendingRequest|null $pendingRequest * @return Response|null */ public function delete(string $url, array $body = [], PendingRequest|null $pendingRequest = null): Response|null; /** * Send a request by given HttpClient request method, url, options * Catches RequestException and ConnectionException * Logs messages * Fires events depending on the configurations * $httpMethod parameter should be provided when $apiClientRequestMethod is HttpClientRequestMethod::SEND * When PendingRequest instance isn't received, new one is created * * @param HttpClientRequestMethod $apiClientRequestMethod * @param string $url * @param array $options * @param PendingRequest|null $pendingRequest * @param HttpMethod|null $httpMethod * @return Response|null */ public function sendRequest( HttpClientRequestMethod $apiClientRequestMethod, string $url, array $options = [], PendingRequest|null $pendingRequest = null, HttpMethod|null $httpMethod = null, ): Response|null; /** * Send request without error handling and event triggering * Throw RequestException when throw is true * * @param HttpClientRequestMethod $apiClientMethod * @param string $url * @param array $options * @param HttpMethod|null $httpMethod * @param bool $throw * @return Response */ public function request( HttpClientRequestMethod $apiClientMethod, string $url, array $options = [], HttpMethod|null $httpMethod = null, bool $throw = false, ): Response; /** * Set PendingRequest when not null value is received * * @param PendingRequest|null $pendingRequest * @return self */ public function setPendingRequest(PendingRequest|null $pendingRequest): self; /** * Get pendingRequest * * @return PendingRequest|null */ public function getPendingRequest(): PendingRequest|null; /** * Determine if HttpResponseSucceeded event is fired * * @param bool $value * @return self */ public function fireEventOnSuccess(bool $value): self; /** * Determine if HttpRequestFailed event is fired * * @param bool $value * @return self */ public function fireEventOnRequestException(bool $value): self; /** * Determine if HttpConnectionFailed event is fired * * @param bool $value * @return self */ public function fireEventOnConnectionException(bool $value): self; /** * Determine if RequestException occurring is logged * * @param bool $value * @return self */ public function logOnRequestException(bool $value): self; /** * Determine if ConnectionException occurring is logged * * @param bool $value * @return self */ public function logOnConnectionException(bool $value): self;
枚举
enum HttpMethod: string { case HEAD = 'HEAD'; case GET = 'GET'; case POST = 'POST'; case PUT = 'PUT'; case PATCH = 'PATCH'; case DELETE = 'DELETE'; case CONNECT = 'CONNECT'; case OPTIONS = 'OPTIONS'; case TRACE = 'TRACE'; }
enum HttpRequestFormat: string { case QUERY = 'query'; case BODY = 'body'; case JSON = 'json'; case FORM_PARAMS = 'form_params'; case MULTIPART = 'multipart'; }
enum HttpClientRequestMethod: string { case GET = 'get'; case HEAD = 'head'; case POST = 'post'; case PATCH = 'patch'; case PUT = 'put'; case DELETE = 'delete'; case SEND = 'send'; }
TokenFromConfigFactoryInterface
/** * Instantiate TokenInterface * When receives $token it is set in TokenInterface instance * $hasRefreshTokenRequest determines instantiating RefreshTokenData * $configKey refers to token configurations in the config file * * @param bool $hasRefreshTokenRequest * @param string $configKey * @param string|null $token = null * @return TokenInterface */ public static function create( bool $hasRefreshTokenRequest = true, string $configKey = 'tokenConfigurationsBase', #[SensitiveParameter] string|null $token = null, ): TokenInterface;
TokenFromDataFactoryInterface
/** * Instantiate TokenInterface * When receives $token it is set in TokenInterface instance * * @param TokenData $tokenData * @param RefreshTokenData|null $refreshTokenData = null * @param int $retries = 3 * @param string|null $token = null * @return TokenInterface */ public static function create( #[SensitiveParameter] TokenData $tokenData, #[SensitiveParameter] RefreshTokenData|null $refreshTokenData = null, int $retries = 3, string|null $token = null, ): TokenInterface;
TokenInterface
/** * Get Access Token * When it's missing request it * When $refresh is true make a request to refresh the token * * @param bool $refresh = false * @return string */ public function get(bool $refresh = false): string;
测试
composer test
变更日志
请参阅 CHANGELOG 了解最近的变化。
安全漏洞
请参阅 我们的安全策略 了解如何报告安全漏洞。
致谢
许可
MIT 许可证 (MIT)。请参阅 许可文件 了解更多信息。