serato / sws-php-sdk
用于与 Serato Web Services 交互的 PHP SDK
Requires
- php: ^7.1 || ^8.0
- guzzlehttp/guzzle: ^6.0.0
- serato/sws-discovery: ^3.0
Requires (Dev)
- aws/aws-sdk-php: ^3.0
- enlightn/security-checker: ^1.4 || ^2
- phpstan/phpstan: ^1.4
- phpstan/phpstan-phpunit: ^1.0
- phpunit/phpunit: ^7 || ^8
- squizlabs/php_codesniffer: ^3.0
- dev-master
- v5.0.1
- v5.0.0
- v4.0.3
- v4.0.2
- v4.0.1
- v4.0.0
- v3.5.2
- v3.5.1
- v3.5.0
- v3.4.0
- v3.3.1
- v3.3.0
- v3.2.0
- v3.1.1
- v3.1.0
- v3.0.1
- v3.0.0
- v2.8.1
- v2.8.0
- v2.7.0
- v2.6.0
- v2.5.0
- v2.4.0
- v2.3.2
- v2.3.1
- v2.3.0
- v2.2.3
- v2.2.2
- v2.2.0
- v2.1.4
- v2.1.3
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.7
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- dev-feature-php8
- dev-WEB-9960
- dev-WEB-5665-test
- dev-WEB-5732
- dev-test-version-bump
This package is auto-updated.
Last update: 2024-09-17 20:17:48 UTC
README
一个用于与 SWS 网络服务交互的 PHP SDK。
注意:目前仅限于使用 服务器端应用程序授权工作流程 的应用程序。
在 Serato Checkout 库中,所有 PHP 代码都位于 Serato\SwsSdk
命名空间中。
风格指南
请确保代码遵循 PHP-FIG PSR-2 编码风格指南
使用 PHP_CodeSniffer 验证您的代码是否符合编码标准
$ ./vendor/bin/phpcs
PHPStan
使用 PHPStan 进行静态代码分析
$ vendor/bin/phpstan analyse
单元测试
PHPUnit 的配置定义在 phpunit.xml 中。
运行测试
$ php vendor/bin/phpunit
用法
关键概念
- 使用
Serato\SwsSdk\Sdk
类提供配置数据给 SDK。一旦配置完毕,可以使用Sdk
实例来创建客户端。 - 客户端与特定的 SWS 网络服务交互。客户端扩展
Serato\SwsSdk\Client
,而Serato\SwsSdk\Client
又扩展GuzzleHttp\Client
。 - 客户端执行命令。命令封装了用于向 SWS 网络服务的特定 HTTP 终端的 HTTP 方法、URI 路径和参数。命令扩展
Serato\SwsSdk\Command
。 - SWS 网络服务端点使用两种基于 HTTP 的身份验证方式之一:HTTP
Basic
或Bearer token
(通过 JWT)。使用Bearer token
身份验证与端点交互的命令需要在执行时提供载体令牌值。 - 当客户端执行命令时,它会返回一个
Serato\SwsSdk\Result
对象或抛出异常。 Serato\SwsSdk\Result
对象封装了来自 SWS 网络服务的 HTTP 响应,并提供了对数据的原生 PHP 数组访问。它们还提供了对底层Psr\Http\Message\ResponseInterface
响应对象的访问。
配置 SDK
使用 Serato\SwsSdk\Sdk::create
静态方法
Serato\SwsSdk\Sdk::create
静态方法是创建 SDK 实例的首选方式。该方法需要一个 Serato\ServiceDiscovery\HostName
实例,并从这个实例派生出 SWS 网络服务的端点 URI。
它还需要一个客户端应用程序 ID 和客户端应用程序密码。
它还可以提供一个 HTTP 请求超时(表示秒数的浮点数),以及一个可调用的函数,该函数在底层的 Guzzle HTTP 库中传输 HTTP 请求(通常用于提供测试目的的模拟请求处理器)。
use Serato\SwsSdk\Sdk; use Serato\ServiceDiscovery\HostName; use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; /* Configure the SDK using a `Serato\ServiceDiscovery\HostName` instance with default timeout and no custom Guzzle handler */ $hostNames = new HostName('production', 1); $sdk = Sdk::create($hostNames, 'my_app_id', 'my_app_secrety_pass'); /* Configure the SDK using a `Serato\ServiceDiscovery\HostName` instance with custom timeout and custom Guzzle handler */ // Create `Serato\ServiceDiscovery\HostName` instance $hostNames = new HostName('test', 2); // Create a mock handler $mock = new MockHandler([ new Response(200, ['X-Foo' => 'Bar']) ]); $handler = HandlerStack::create($mock); $sdk = Sdk::create($hostNames, 'my_app_id', 'my_app_secrety_pass', 3.2, $handler);
使用 Serato\SwsSdk\Sdk
构造函数
几乎在所有情况下,Serato\SwsSdk\Sdk::create
方法是配置 SDK 的首选方式。但如果您需要向 SDK 提供非标准配置(例如,使用来自不同环境的不同的服务端点),您可以直接调用 SDK 构造函数。
Serato\SwsSdk\Sdk
构造函数接受一个 $args
数组、一个客户端应用程序 ID 和客户端应用程序密码。
$args
用于指定各种 SWS 网络服务的端点,并提供对底层 GuzzleHttp\Client
的额外配置。
可以通过设置 $args
的 Sdk::BASE_URI
键来指定自定义端点,该键为具有以下键的数组
Sdk::BASE_URI_ID
Sdk::BASE_URI_LICENSE
Sdk::BASE_URI_PROFILE
Sdk::BASE_URI_ECOM
Sdk::BASE_URI_DA
Sdk::BASE_URI_NOTIFICATIONS
每个键的值是对应 SWS 网络服务的完整基本 URI(包括协议)。
$args
可以接受一个 'timeout'
键,用于设置所有请求的超时时间。超时值是表示请求超时前秒数的浮点数。
$args
还可以接受一个 'handler'
键,它定义了一个自定义的 HTTP 处理器,该处理器由底层的 GuzzleHttp 库使用。其主要用途是模拟各种 HTTP 响应(有关更多信息,请参见下面的 测试客户端)。
use Serato\SwsSdk\Sdk; use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; /* Configure the SDK to use custom SWS endpoints, a non-standard timeout and a Guzzle MockHandler */ // Create a mock handler $mock = new MockHandler([ new Response(200, ['X-Foo' => 'Bar']) ]); $handler = HandlerStack::create($mock); $args = [ Sdk::BASE_URI => [ Sdk::BASE_URI_ID => 'http://id.server.com', Sdk::BASE_URI_LICENSE => 'https://license.server.com', Sdk::BASE_URI_PROFILE => 'https://profile.server.com', Sdk::BASE_URI_ECOM => 'https://ecom.server.com' ], 'handler' => $handler, 'timeout' => 3.2 ]; $sdk = new Sdk($args, 'my_app_id', 'my_app_secrety_pass');
创建客户端
可以使用 Serato\SwsSdk\Sdk
的实例来创建服务客户端。
客户端通过传递给 Serato\SwsSdk\Sdk
实例的配置参数与特定的 SWS 服务交互。
目前有六个客户端可用
Serato\SwsSdk\Identity\IdentityClient
- 与 SWS 身份服务交互的客户端。Serato\SwsSdk\License\LicenseClient
- 与 SWS 许可服务交互的客户端。Serato\SwsSdk\Profile\ProfileClient
- 与 SWS 个人资料服务交互的客户端。Serato\SwsSdk\Ecom\EcomClient
- 与 SWS Ecom 服务交互的客户端。Serato\SwsSdk\Da\DaClient
- 与 SWS DA 服务交互的客户端。Serato\SwsSdk\Notifications\NotificationsClient
- 与 SWS 通知服务交互的客户端。
use Serato\SwsSdk\Sdk; /* Create clients from an Sdk instance */ $args = ['env' => Sdk::ENV_PRODUCTION]; $sdk = new Sdk($args, 'my_app_id', 'my_app_secrety_pass'); $identityClient = $sdk->createIdentityClient(); $licenseClient = $sdk->createLicenseClient(); $profileClient = $sdk->createProfileClient(); $ecomClient = $sdk->createEcomClient();
执行命令
命令对应于 SWS 服务上的特定端点。命令需要参数,这些参数直接映射到对应端点允许的请求参数。
PHP API 文档列出了每个命令类的允许参数。
可以显式创建命令并将其传递给 Serato\SwsSdk\Client::executeCommand
方法。但使用客户端的魔术方法来将命令映射到客户端方法名会更简单。
PHP API 文档为每个命令类提供了魔术方法名。
use Serato\SwsSdk\Sdk; use Serato\SwsSdk\License\Command\ProductGet; $args = ['env' => Sdk::ENV_PRODUCTION]; $sdk = new Sdk($args, 'my_app_id', 'my_app_secrety_pass'); $identityClient = $sdk->createIdentityClient(); $licenseClient = $sdk->createLicenseClient(); /* Command that uses HTTP `Basic` auth */ // Explicitly create a `ProductGet` command and execute it $commandArgs = ['product_id' => 'SDJ-1234-1234']; $command = new ProductGet('my_app', 'my_pass', 'https://sws.endpoint.url', $commandArgs); $result = $licenseClient->executeCommand($command); // Simpler: Use the `LicenseClient::getProduct` magic method to execute the `ProductGet` command $commandArgs = ['product_id' => 'SDJ-1234-1234']; $result = $licenseClient->getProduct($commandArgs); /* Command that uses `Bearer token` auth */ // Explicitly create a `UserGet` command and execute it $bearerToken = 'my_bearer_token_value'; $command = new UserGet('my_app', 'my_pass', 'https://sws.endpoint.url'); $result = $identityClient->executeCommand($command, $bearerToken); // Simpler: Use the `IdentityClient::getUser` magic method to execute the `UserGet` command $result = $identityClient->getProduct($bearerToken);
处理结果
成功执行的命令返回一个 Serato\SwsSdk\Result
实例。
Result
对象从 SWS 网络服务获取响应并解析消息体,以便可以使用原生的 PHP 数组访问器语法访问响应体的内容。
Result
对象还有一个 Result::getResponse
方法,它返回底层的 Psr\Http\Message\ResponseInterface
响应对象。
use Serato\SwsSdk\Sdk; use Serato\SwsSdk\License\Command\ProductGet; $args = ['env' => Sdk::ENV_PRODUCTION]; $sdk = new Sdk($args, 'my_app_id', 'my_app_secrety_pass'); $licenseClient = $sdk->createLicenseClient(); $commandArgs = ['product_id' => 'SDJ-1234-1234']; $result = $licenseClient->getProduct($commandArgs); // Echo the product ID echo $result['id']; // Echo the number of licenses in the product echo count($result['licenses']); // Access the `Psr\Http\Message\ResponseInterface` response object $response = $result->getResponse();
异常
当命令执行导致 SWS 网络服务的非 200 HTTP 响应时,将抛出异常。
SDK 中的所有异常类都扩展了 Serato\SwsSdk\Exception\ResponseException
。 ResponseException
扩展了基于 PHP 的基本 RuntimeException
类。
ResponseException
类有一个 ResponseException::getResult
方法,该方法返回一个 Result
对象,从而提供对底层 Web 服务响应的访问。
特定的异常类处理每种预期的非 200 HTTP 响应。异常类的 code
属性在每个子异常类中以两种不同方式之一使用
Serato\SwsSdk\Exception\AccessDeniedException
:code
是响应消息体中指定的错误代码。Serato\SwsSdk\Exception\BadRequestException
:code
是响应消息体中指定的错误代码。Serato\SwsSdk\Exception\ResourceNotFoundException
:code
是 HTTP 响应代码。例如,404。Serato\SwsSdk\Exception\ServerApplicationErrorException
:code
是 HTTP 响应代码。例如,500。Serato\SwsSdk\Exception\ServiceUnavailableException
:code
是 HTTP 响应代码。例如,503。
导致连接错误(超时、失败的 DNS 查找等)的请求不会抛出 SDK 特定的异常,而是抛出 Guzzle 提供的 GuzzleHttp\Exception\ConnectException
。
测试客户端
因为SDK中的客户端可以扩展对SWS服务的GuzzleHttp\Client
请求,所以可以使用Guzzle的GuzzleHttp\Handler\MockHandler
进行模拟。
Guzzle的[官方文档](http://guzzle.readthedocs.io/en/latest/testing.html)提供了如何创建模拟响应并将它们提供给GuzzleHttp\Handler\MockHandler
实例的详细概述。
然后,可以通过Serato\SwsSdk\Sdk
类将模拟处理程序提供给SwsSdk客户端。
use Serato\SwsSdk\Sdk; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; // Create a mock handler and queue two responses. $mock = new MockHandler([ new Response(200, [/* Headers */], '{"id":"SDJ-1111-11111"}'), new Response(200, [/* Headers */], '{"id":"SDJ-2222-22222"}') ]); $handler = HandlerStack::create($mock); $args = [ 'env' => Sdk::ENV_STAGING, 'handler' => $handler ]; $sdk = new Sdk($args, 'my_app_id', 'my_app_secrety_pass'); // Client is created with the `handler` option as specified in the `Sdk` constructor $licenseClient = $sdk->createLicenseClient(); // Execute the first command. The mock handler returns the first response from the stack. $result = $licenseClient->getProduct(['product_id' => 'SDJ-1234-1234']); // Will echo 'SDJ-1111-11111' echo $result['id']; // Will echo the raw response body '{"id":"SDJ-1111-11111"}' echo $result->getResponse()->getBody(); // Execute the first second. The mock handler returns the second response from the stack. $result = $licenseClient->getProduct(['product_id' => 'SDJ-1234-1234']); // Will echo 'SDJ-2222-22222' echo $result['id']; // Will echo the raw response body '{"id":"SDJ-2222-22222"}' echo $result->getResponse()->getBody();
模拟处理程序堆栈还可以包括异常。
use Serato\SwsSdk\Sdk; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; use Exception; // Create a mock handler and queue two responses. $mock = new MockHandler([ new Response(200, [/* Headers */], '{"id":"SDJ-1111-11111"}'), new Exception ]); $handler = HandlerStack::create($mock); $args = [ 'env' => Sdk::ENV_STAGING, 'handler' => $handler ]; $sdk = new Sdk($args, 'my_app_id', 'my_app_secrety_pass'); // Client is created with the `handler` option as specified in the `Sdk` constructor $licenseClient = $sdk->createLicenseClient(); // Execute the first command. The mock handler returns the first response from the stack. $result = $licenseClient->getProduct(['product_id' => 'SDJ-1234-1234']); // Will echo 'SDJ-1111-11111' echo $result['id']; // Throws Exception $result = $licenseClient->getProduct(['product_id' => 'SDJ-5678-4321']);