-
-
Notifications
You must be signed in to change notification settings - Fork 599
Add client builder #480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add client builder #480
Changes from 9 commits
86d9d00
51ba284
7153101
f2b1a77
02b38a2
3fe4dbc
bd2dd41
461f27b
fa4d1d9
a8f60a1
511775a
c915187
3160b9c
38ceb97
0efb593
d7cde53
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,20 +5,14 @@ | |
use Github\Api\ApiInterface; | ||
use Github\Exception\InvalidArgumentException; | ||
use Github\Exception\BadMethodCallException; | ||
use Github\HttpClient\Builder; | ||
use Github\HttpClient\Plugin\Authentication; | ||
use Github\HttpClient\Plugin\GithubExceptionThrower; | ||
use Github\HttpClient\Plugin\History; | ||
use Github\HttpClient\Plugin\PathPrepend; | ||
use Http\Client\Common\HttpMethodsClient; | ||
use Http\Client\Common\Plugin; | ||
use Http\Client\Common\PluginClient; | ||
use Http\Client\HttpClient; | ||
use Http\Discovery\HttpClientDiscovery; | ||
use Http\Discovery\MessageFactoryDiscovery; | ||
use Http\Discovery\StreamFactoryDiscovery; | ||
use Http\Discovery\UriFactoryDiscovery; | ||
use Http\Message\MessageFactory; | ||
use Nyholm\Psr7\Factory\StreamFactory; | ||
use Psr\Cache\CacheItemPoolInterface; | ||
|
||
/** | ||
|
@@ -98,45 +92,9 @@ class Client | |
private $apiVersion; | ||
|
||
/** | ||
* The object that sends HTTP messages | ||
* | ||
* @var HttpClient | ||
*/ | ||
private $httpClient; | ||
|
||
/** | ||
* A HTTP client with all our plugins | ||
* | ||
* @var PluginClient | ||
*/ | ||
private $pluginClient; | ||
|
||
/** | ||
* @var MessageFactory | ||
*/ | ||
private $messageFactory; | ||
|
||
/** | ||
* @var StreamFactory | ||
*/ | ||
private $streamFactory; | ||
|
||
/** | ||
* @var Plugin[] | ||
*/ | ||
private $plugins = []; | ||
|
||
/** | ||
* True if we should create a new Plugin client at next request. | ||
* @var bool | ||
*/ | ||
private $httpClientModified = true; | ||
|
||
/** | ||
* Http headers | ||
* @var array | ||
* @var Builder | ||
*/ | ||
private $headers = []; | ||
private $httpClientBuilder; | ||
|
||
/** | ||
* @var History | ||
|
@@ -146,27 +104,26 @@ class Client | |
/** | ||
* Instantiate a new GitHub client. | ||
* | ||
* @param HttpClient|null $httpClient | ||
* @param string|null $apiVersion | ||
* @param string|null $enterpriseUrl | ||
* @param Builder|null $httpClient | ||
* @param string|null $apiVersion | ||
* @param string|null $enterpriseUrl | ||
*/ | ||
public function __construct(HttpClient $httpClient = null, $apiVersion = null, $enterpriseUrl = null) | ||
public function __construct(Builder $httpClientBuilder = null, $apiVersion = null, $enterpriseUrl = null) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO it's better to leave old constructor and create new builder inline or support both. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe keep the old constructor indeed but deprecated it (throw deprecation warning) and use the new constructor in 3.0. Or you could say use the new constructor from now on as 2.0 stable is not yet released There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My idea is that client should always be constructed without extra manipulations, i.e.
maybe static factory can be a possible solution. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right about that, it should be a simple as possible to instantiate and use the client There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did not like the new constructor myself to be honest. Should I add another constructor argument with the builder? |
||
{ | ||
$this->httpClient = $httpClient ?: HttpClientDiscovery::find(); | ||
$this->messageFactory = MessageFactoryDiscovery::find(); | ||
$this->streamFactory = StreamFactoryDiscovery::find(); | ||
|
||
$this->responseHistory = new History(); | ||
$this->addPlugin(new GithubExceptionThrower()); | ||
$this->addPlugin(new Plugin\HistoryPlugin($this->responseHistory)); | ||
$this->addPlugin(new Plugin\RedirectPlugin()); | ||
$this->addPlugin(new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri('https://api.github.com'))); | ||
$this->addPlugin(new Plugin\HeaderDefaultsPlugin(array( | ||
'User-Agent' => 'php-github-api (http://github.com/KnpLabs/php-github-api)', | ||
$this->httpClientBuilder = $builder = $httpClientBuilder ?: new Builder(); | ||
|
||
$builder->addPlugin(new GithubExceptionThrower()); | ||
$builder->addPlugin(new Plugin\HistoryPlugin($this->responseHistory)); | ||
$builder->addPlugin(new Plugin\RedirectPlugin()); | ||
$builder->addPlugin(new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri('https://api.github.com'))); | ||
$builder->addPlugin(new Plugin\HeaderDefaultsPlugin(array( | ||
'User-Agent' => 'php-github-api (http://github.com/KnpLabs/php-github-api)', | ||
'Accept' => sprintf('application/vnd.github.%s+json', $this->getApiVersion()), | ||
))); | ||
|
||
$this->apiVersion = $apiVersion ?: 'v3'; | ||
$this->addHeaders(['Accept' => sprintf('application/vnd.github.%s+json', $this->apiVersion)]); | ||
$builder->addHeaders(['Accept' => sprintf('application/vnd.github.%s+json', $this->apiVersion)]); | ||
|
||
if ($enterpriseUrl) { | ||
$this->setEnterpriseUrl($enterpriseUrl); | ||
|
@@ -313,15 +270,15 @@ public function authenticate($tokenOrLogin, $password = null, $authMethod = null | |
|
||
if (null === $authMethod && in_array($password, array(self::AUTH_URL_TOKEN, self::AUTH_URL_CLIENT_ID, self::AUTH_HTTP_PASSWORD, self::AUTH_HTTP_TOKEN, self::AUTH_JWT))) { | ||
$authMethod = $password; | ||
$password = null; | ||
$password = null; | ||
} | ||
|
||
if (null === $authMethod) { | ||
$authMethod = self::AUTH_HTTP_PASSWORD; | ||
} | ||
|
||
$this->removePlugin(Authentication::class); | ||
$this->addPlugin(new Authentication($tokenOrLogin, $password, $authMethod)); | ||
$this->getHttpClientBuilder()->removePlugin(Authentication::class); | ||
$this->getHttpClientBuilder()->addPlugin(new Authentication($tokenOrLogin, $password, $authMethod)); | ||
} | ||
|
||
/** | ||
|
@@ -331,64 +288,12 @@ public function authenticate($tokenOrLogin, $password = null, $authMethod = null | |
*/ | ||
private function setEnterpriseUrl($enterpriseUrl) | ||
{ | ||
$this->removePlugin(Plugin\AddHostPlugin::class); | ||
$this->removePlugin(PathPrepend::class); | ||
|
||
$this->addPlugin(new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri($enterpriseUrl))); | ||
$this->addPlugin(new PathPrepend(sprintf('/api/%s/', $this->getApiVersion()))); | ||
} | ||
|
||
/** | ||
* Add a new plugin to the end of the plugin chain. | ||
* | ||
* @param Plugin $plugin | ||
*/ | ||
public function addPlugin(Plugin $plugin) | ||
{ | ||
$this->plugins[] = $plugin; | ||
$this->httpClientModified = true; | ||
} | ||
$builder = $this->getHttpClientBuilder(); | ||
$builder->removePlugin(Plugin\AddHostPlugin::class); | ||
$builder->removePlugin(PathPrepend::class); | ||
|
||
/** | ||
* Remove a plugin by its fully qualified class name (FQCN). | ||
* | ||
* @param string $fqcn | ||
*/ | ||
public function removePlugin($fqcn) | ||
{ | ||
foreach ($this->plugins as $idx => $plugin) { | ||
if ($plugin instanceof $fqcn) { | ||
unset($this->plugins[$idx]); | ||
$this->httpClientModified = true; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @return HttpMethodsClient | ||
*/ | ||
public function getHttpClient() | ||
{ | ||
if ($this->httpClientModified) { | ||
$this->httpClientModified = false; | ||
$this->pushBackCachePlugin(); | ||
|
||
$this->pluginClient = new HttpMethodsClient( | ||
new PluginClient($this->httpClient, $this->plugins), | ||
$this->messageFactory | ||
); | ||
} | ||
|
||
return $this->pluginClient; | ||
} | ||
|
||
/** | ||
* @param HttpClient $httpClient | ||
*/ | ||
public function setHttpClient(HttpClient $httpClient) | ||
{ | ||
$this->httpClientModified = true; | ||
$this->httpClient = $httpClient; | ||
$builder->addPlugin(new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri($enterpriseUrl))); | ||
$builder->addPlugin(new PathPrepend(sprintf('/api/%s/', $this->getApiVersion()))); | ||
} | ||
|
||
/** | ||
|
@@ -399,30 +304,6 @@ public function getApiVersion() | |
return $this->apiVersion; | ||
} | ||
|
||
/** | ||
* Clears used headers. | ||
*/ | ||
public function clearHeaders() | ||
{ | ||
$this->headers = array( | ||
'Accept' => sprintf('application/vnd.github.%s+json', $this->getApiVersion()), | ||
); | ||
|
||
$this->removePlugin(Plugin\HeaderAppendPlugin::class); | ||
$this->addPlugin(new Plugin\HeaderAppendPlugin($this->headers)); | ||
} | ||
|
||
/** | ||
* @param array $headers | ||
*/ | ||
public function addHeaders(array $headers) | ||
{ | ||
$this->headers = array_merge($this->headers, $headers); | ||
|
||
$this->removePlugin(Plugin\HeaderAppendPlugin::class); | ||
$this->addPlugin(new Plugin\HeaderAppendPlugin($this->headers)); | ||
} | ||
|
||
/** | ||
* Add a cache plugin to cache responses locally. | ||
* | ||
|
@@ -431,16 +312,15 @@ public function addHeaders(array $headers) | |
*/ | ||
public function addCache(CacheItemPoolInterface $cachePool, array $config = []) | ||
{ | ||
$this->removeCache(); | ||
$this->addPlugin(new Plugin\CachePlugin($cachePool, $this->streamFactory, $config)); | ||
$this->getHttpClientBuilder()->addCache($cachePool, $config); | ||
} | ||
|
||
/** | ||
* Remove the cache plugin | ||
* Remove the cache plugin. | ||
*/ | ||
public function removeCache() | ||
{ | ||
$this->removePlugin(Plugin\CachePlugin::class); | ||
$this->getHttpClientBuilder()->removeCache(); | ||
} | ||
|
||
/** | ||
|
@@ -460,7 +340,6 @@ public function __call($name, $args) | |
} | ||
|
||
/** | ||
* | ||
* @return null|\Psr\Http\Message\ResponseInterface | ||
*/ | ||
public function getLastResponse() | ||
|
@@ -469,20 +348,18 @@ public function getLastResponse() | |
} | ||
|
||
/** | ||
* Make sure to move the cache plugin to the end of the chain | ||
* @return HttpMethodsClient | ||
*/ | ||
private function pushBackCachePlugin() | ||
public function getHttpClient() | ||
{ | ||
$cachePlugin = null; | ||
foreach ($this->plugins as $i => $plugin) { | ||
if ($plugin instanceof Plugin\CachePlugin) { | ||
$cachePlugin = $plugin; | ||
unset($this->plugins[$i]); | ||
|
||
$this->plugins[] = $cachePlugin; | ||
return $this->getHttpClientBuilder()->getHttpClient(); | ||
} | ||
|
||
return; | ||
} | ||
} | ||
/** | ||
* @return Builder | ||
*/ | ||
protected function getHttpClientBuilder() | ||
{ | ||
return $this->httpClientBuilder; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changed part is already added for RC5 right under
added
(line 32 in your changed file)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's correct. Thank you.