From d4a3cf8d423d1ef8a305a44dc4a25939ddc2f877 Mon Sep 17 00:00:00 2001 From: Neur0toxine Date: Mon, 28 Dec 2020 17:49:26 +0300 Subject: [PATCH] validate AppData, easier client instantiation for those who don't want to look into the complex inner logic --- README.md | 38 ++++++++----- src/Component/AppData.php | 2 +- src/Factory/TopClientFactory.php | 53 +++++++++++++++++++ src/TopClient/TopClient.php | 1 + .../Tests/Factory/TopClientFactoryTest.php | 41 ++++++++++++++ 5 files changed, 122 insertions(+), 13 deletions(-) create mode 100644 src/Factory/TopClientFactory.php create mode 100644 tests/RetailCrm/Tests/Factory/TopClientFactoryTest.php diff --git a/README.md b/README.md index 5d72101..a75f29b 100644 --- a/README.md +++ b/README.md @@ -7,25 +7,23 @@ API client implementation for AliExpress TOP. ## Usage -1. This library uses `php-http/httplug` under the hood. If you don't want to bother with details, just install library and it's dependencies through Composer: +1. This library uses `php-http/httplug` under the hood. If you don't want to bother with details, just install library and it's dependencies via Composer: ```sh composer require php-http/curl-client nyholm/psr7 php-http/message retailcrm/aliexpress-top-client ``` Details about those third-party libraries and why you need to install them can be found [here](http://docs.php-http.org/en/latest/httplug/users.html). -2. Instantiate client like that: +2. Instantiate client using `TopClientFactory`: ```php use RetailCrm\Component\AppData; -use RetailCrm\Builder\TopClientBuilder; -use RetailCrm\Builder\ContainerBuilder; -use RetailCrm\Component\Authenticator\TokenAuthenticator; +use RetailCrm\Factory\TopClientFactory; -$appData = new AppData(AppData::OVERSEAS_ENDPOINT, 'appKey', 'appSecret'); -$client = TopClientBuilder::create() - ->setContainer(ContainerBuilder::create()->build()) - ->setAppData($appData) - ->setAuthenticator(new TokenAuthenticator('session token here')) - ->build(); +$client = TopClientFactory::createClient( + AppData::OVERSEAS_ENDPOINT, + 'appKey', + 'appSecret', + 'session token here' +); ``` 3. Create and fill request data. All requests and responses use the same naming: part of the namespace is the first word in the request name, and everything else is in the request DTO class name. Requests live under `RetailCrm\Model\Request` namespace, and responses can be found in the `RetailCrm\Model\Response` namespace. @@ -75,5 +73,21 @@ $client = TopClientBuilder::create() ->build(); ``` Logger should implement `Psr\Log\LoggerInterface` (PSR-3), HTTP client should implement `Psr\Http\TopClient\TopClientInterface` (PSR-18), HTTP objects must be compliant to PSR-7. +You can use your own container if you want to - it must be compliant to PSR-11. This is strongly discouraged because it'll be much easier to just integrate library with your own application, and your own DI system. + +The simplest example of client initialization without using `TopClientFactory` looks like this: +```php +use RetailCrm\Component\AppData; +use RetailCrm\Builder\TopClientBuilder; +use RetailCrm\Builder\ContainerBuilder; +use RetailCrm\Component\Authenticator\TokenAuthenticator; + +$appData = new AppData(AppData::OVERSEAS_ENDPOINT, 'appKey', 'appSecret'); +$client = TopClientBuilder::create() + ->setContainer(ContainerBuilder::create()->build()) + ->setAppData($appData) + ->setAuthenticator(new TokenAuthenticator('session token here')) + ->build(); +``` +In fact, `TopClientFactory` works just like this under the hood. -You can use your own container - it must be compliant to PSR-11. This is strongly discouraged because it'll be much easier to just integrate library with your own application, and your own DI system. diff --git a/src/Component/AppData.php b/src/Component/AppData.php index 72cf6cd..8f5996d 100644 --- a/src/Component/AppData.php +++ b/src/Component/AppData.php @@ -26,7 +26,7 @@ class AppData implements AppDataInterface /** * @var string $serviceUrl * @Assert\Url() - * @Assert\Choice(choices=Client::AVAILABLE_ENDPOINTS, message="Invalid endpoint provided.") + * @Assert\Choice(choices=AppData::AVAILABLE_ENDPOINTS, message="Invalid endpoint provided.") */ protected $serviceUrl; diff --git a/src/Factory/TopClientFactory.php b/src/Factory/TopClientFactory.php new file mode 100644 index 0000000..0864c2d --- /dev/null +++ b/src/Factory/TopClientFactory.php @@ -0,0 +1,53 @@ +setContainer(ContainerBuilder::create()->build()) + ->setAppData($appData); + + if ('' !== $token) { + $builder->setAuthenticator(new TokenAuthenticator($token)); + } + + return $builder->build(); + } +} diff --git a/src/TopClient/TopClient.php b/src/TopClient/TopClient.php index 4047ee6..9c7406b 100644 --- a/src/TopClient/TopClient.php +++ b/src/TopClient/TopClient.php @@ -108,6 +108,7 @@ class TopClient implements TopClientInterface public function validateSelf(): void { $this->validate($this); + $this->validate($this->appData); } /** diff --git a/tests/RetailCrm/Tests/Factory/TopClientFactoryTest.php b/tests/RetailCrm/Tests/Factory/TopClientFactoryTest.php new file mode 100644 index 0000000..0b51820 --- /dev/null +++ b/tests/RetailCrm/Tests/Factory/TopClientFactoryTest.php @@ -0,0 +1,41 @@ +expectException(ValidationException::class); + TopClientFactory::createClient('https://example.com', 'appKey', 'appSecret'); + } +}