feat : Decorator Http
This commit is contained in:
@@ -45,7 +45,12 @@ class DecoratorController extends AbstractController
|
||||
return (new AopService)->handle();
|
||||
}
|
||||
|
||||
public function http()
|
||||
/**
|
||||
* http 装饰器
|
||||
* @return array
|
||||
*/
|
||||
#[RequestMapping(path: 'http', methods: 'GET')]
|
||||
public function http(): array
|
||||
{
|
||||
return (new HttpService)->handle();
|
||||
}
|
||||
|
||||
21
app/Interface/Test/Decorator/HttpClientInterface.php
Normal file
21
app/Interface/Test/Decorator/HttpClientInterface.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Interface\Test\Decorator;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
interface HttpClientInterface
|
||||
{
|
||||
/**
|
||||
* 请求装饰器接口
|
||||
* @param string $method
|
||||
* @param string $url
|
||||
* @param array $options
|
||||
* @return mixed
|
||||
*/
|
||||
public function request(
|
||||
string $method,
|
||||
string $url,
|
||||
array $options = []
|
||||
): mixed;
|
||||
}
|
||||
28
app/Lib/Request/GuzzleHttpClient.php
Normal file
28
app/Lib/Request/GuzzleHttpClient.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Lib\Request;
|
||||
|
||||
use App\Interface\Test\Decorator\HttpClientInterface;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class GuzzleHttpClient implements HttpClientInterface
|
||||
{
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $url
|
||||
* @param array $options
|
||||
* @return ResponseInterface
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function request(
|
||||
string $method,
|
||||
string $url,
|
||||
array $options = []
|
||||
): ResponseInterface
|
||||
{
|
||||
$client = new Client();
|
||||
return $client->request($method, $url, $options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
* @web_site https://ctexthuang.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Test\Decorator\Http;
|
||||
|
||||
use App\Interface\Test\Decorator\HttpClientInterface;
|
||||
use App\Interface\Test\Decorator\LoggerInterface;
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class LoggableHttpClientService implements HttpClientInterface
|
||||
{
|
||||
/**
|
||||
* @var HttpClientInterface
|
||||
*/
|
||||
private HttpClientInterface $httpClient;
|
||||
|
||||
/**
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
HttpClientInterface $httpClient,
|
||||
LoggerInterface $logger,
|
||||
)
|
||||
{
|
||||
$this->httpClient = $httpClient;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $url
|
||||
* @param array $options
|
||||
* @return ResponseInterface|false
|
||||
* @throws Exception
|
||||
*/
|
||||
public function request(string $method, string $url, array $options = []): ResponseInterface|false
|
||||
{
|
||||
$this->logger->log("Sending {{$method}} request to {{$url}}");
|
||||
|
||||
try {
|
||||
$response = $this->httpClient->request($method, $url, $options);
|
||||
$this->logger->log("Request to {{$url}} completed successfully");
|
||||
return $response;
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error("Request to {{$url} failed: {{$e->getMessage()}}}");
|
||||
// throw $e;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
* @web_site https://ctexthuang.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Test\Decorator\Http;
|
||||
|
||||
use App\Interface\Test\Decorator\HttpClientInterface;
|
||||
use App\Interface\Test\Decorator\LoggerInterface;
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class RetryableHttpClientService implements HttpClientInterface
|
||||
{
|
||||
/**
|
||||
* 请求接口注入
|
||||
* @var HttpClientInterface
|
||||
*/
|
||||
protected HttpClientInterface $httpClient;
|
||||
|
||||
/**
|
||||
* 日志接口注入
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* 最大重试
|
||||
* @var int
|
||||
*/
|
||||
private int $maxRetries;
|
||||
|
||||
public function __construct(
|
||||
HttpClientInterface $httpClient,
|
||||
LoggerInterface $logger,
|
||||
int $maxRetries = 3
|
||||
)
|
||||
{
|
||||
$this->httpClient = $httpClient;
|
||||
$this->maxRetries = $maxRetries;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param string $url
|
||||
* @param array $options
|
||||
* @return false|ResponseInterface
|
||||
*/
|
||||
public function request(string $method, string $url, array $options = []): ResponseInterface|false
|
||||
{
|
||||
var_dump('maxRetries:'.$this->maxRetries);
|
||||
$retryCount = 0;
|
||||
|
||||
while ($retryCount < $this->maxRetries) {
|
||||
try {
|
||||
return $this->httpClient->request($method, $url, $options);
|
||||
} catch (Exception $e) {
|
||||
$this->logger->error('重试请求'.$url.':第'.$retryCount.'次'.$e->getMessage());
|
||||
$retryCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,31 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Test\Decorator;
|
||||
|
||||
use App\Interface\Test\Decorator\HttpClientInterface;
|
||||
use App\Service\Test\TestBaseService;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
|
||||
class HttpService extends TestBaseService
|
||||
{
|
||||
public function handle()
|
||||
/**
|
||||
* @var HttpClientInterface
|
||||
*/
|
||||
#[Inject]
|
||||
protected HttpClientInterface $httpClient;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function handle(): array
|
||||
{
|
||||
return $this->return->success();
|
||||
$response = $this->httpClient->request('GET','https://api.example.com/data',[
|
||||
'timeout' => 5
|
||||
]);
|
||||
|
||||
if (!$response) return $this->return->error();
|
||||
|
||||
return $this->return->success('请求成功',[
|
||||
'body' => json_decode($response->getBody()->getContents(), true),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -11,14 +11,16 @@ declare(strict_types=1);
|
||||
*/
|
||||
|
||||
use App\Interface\Test\Adapter\CacheInterface;
|
||||
use App\Interface\Test\Decorator\HttpClientInterface;
|
||||
use App\Interface\Test\Decorator\LoggerInterface;
|
||||
use App\Service\Test\Adapter\Cache\FileCacheAdapter;
|
||||
use App\Lib\Request\GuzzleHttpClient;
|
||||
use App\Service\Test\Adapter\Cache\RedisCacheService;
|
||||
use App\Service\Test\Decorator\Container\BasicFileLogger;
|
||||
use App\Service\Test\Decorator\Container\CriticalLoggerDecorator;
|
||||
use App\Service\Test\Decorator\Container\IpLoggerDecorator;
|
||||
use App\Service\Test\Decorator\Container\TimestampLoggerDecorator;
|
||||
use Hyperf\Logger\LoggerFactory;
|
||||
use App\Service\Test\Decorator\Http\LoggableHttpClientService;
|
||||
use App\Service\Test\Decorator\Http\RetryableHttpClientService;
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
return [
|
||||
@@ -30,4 +32,10 @@ return [
|
||||
$logger = make(IpLoggerDecorator::class, ['logger' => $logger]);
|
||||
return make(CriticalLoggerDecorator::class, ['logger' => $logger]);
|
||||
},
|
||||
HttpClientInterface::class => function () {
|
||||
$client = make(GuzzleHttpClient::class);
|
||||
$logger = make(BasicFileLogger::class);
|
||||
$client = make(RetryableHttpClientService::class,['httpClient' => $client , 'logger' => $logger , 'maxRetries' => 2]);
|
||||
return make(LoggableHttpClientService::class,['httpClient' => $client , 'logger' => $logger]);
|
||||
}
|
||||
];
|
||||
|
||||
@@ -24,7 +24,10 @@ Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
|
||||
### Decorator aop test
|
||||
GET {{host}}/decorator/test/aop
|
||||
GET {{host}}/decorator/test/aop?user_id=12
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
user_id=12
|
||||
|
||||
### Decorator http test
|
||||
GET {{host}}/decorator/test/http
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Reference in New Issue
Block a user