mt-olympus/hermes

使用 Hal 的 REST API 客户端

1.5.2 2020-03-12 16:17 UTC

README

Hermes 是一个用于通过 Hal 消费 Restful API 的 PHP 库,类似于 Apigility

它是其他 Olympus 服务的核心 IPC 方法。

可以使用纯 PHP 或任何 PHP 框架,如 ZendFramework 2 和 Zend-Expressive。

要求

  • PHP >= 7.2
  • Laminas Http >= 2.4
  • Laminas ServiceManager >= 2.5
  • nocarrier/hal >= 0.9

您可以添加模块 hermes-loslog 来记录请求。

安装

使用 composer(推荐)

php composer.phar require mt-olympus/hermes

配置

您至少需要配置 API URI。

如果您使用实现了 container-interopt 的框架,可以使用以下配置

将此模块中的 hermes.global.php.dist 复制到您的应用程序配置文件夹,并进行必要的更改。

有关 http-client 选项的更多信息,请参阅官方文档 Laminas\Http\Client 选项

'hermes' => [
    'uri' => 'https://:8000',
    'depth' => 0,
    'http_client' => [
        'options' => [
            'timeout'       => 60,
            'sslverifypeer' => false,
            'keepalive'     => true,
            'adapter'       => 'Laminas\Http\Client\Adapter\Socket',
        ],
    ],
    'headers' => [
        'Accept'       => 'application/hal+json',
        'Content-Type' => 'application/json',
    ],
]

用法

创建客户端

您可以使用上述配置或手动使用 Hermes\Api\ClientFactory

$httpClient = new Laminas\Http\Client('http://127.0.0.1', []);
$client = new Hermes\Apt\Client($httpClient, 10);

注入 Cerberus 断路器

您可以使用带有断路器的客户端来控制故障和成功,避免不必要的尝试。

有关 cerberus 的更多信息,请参阅其 自己的存储库

$httpClient = new Laminas\Http\Client('http://127.0.0.1', []);
$storage = Laminas\Cache\StorageFactory\StorageFactory::factory([
            'adapter' => [
                'name' => 'memory',
                'options' => [
                    'namespace' => 'my-service',
                ],
            ],
            'plugins' => [
                'exception_handler' => [
                    'throw_exceptions' => false,
                ],
            ],
        ]);
$cerberus = new Cerberus($storage, 2, 2);

// Create a new client
$client = new Hermes\Apt\Client($httpClient, 10, $cerberus, 'my-service');

// Or add it to a previously created client 
$client->setCircuitBreaker($cerberus);
$client->setServiceName('my-service');

单个资源

/* @var \Hermes\Api\Client $client */
$client = $this->getServiceLocator()->get('hermes');
/* @var \Hermes\Resource\Resource $ret */
$ret = $client->get('/album/1');

// $data is an array with all data and resources (_embedded) from the response
$data = $ret->getData();

// $data is an array only with data from the response
$data = $ret->getData(false);

集合

/* @var \Hermes\Api\Client $client */
$client = $this->getServiceLocator()->get('hermes');

// Setting depth of _embedded resources to 10
$client->setDepth(10);

/* @var \Hermes\Resource\Resource $ret */
$ret = $client->get('/album',['year' => 2015]);

// $data is an array with all data and resources (_embedded) from the response
$data = $ret->getData();

// $data is an array with the first album resource from the response
$data = $ret->getFirstResource('album');

// $data is an array with the all album resources from the response
$data = $ret->getResources('album');

// $data is an array with the all resources from the response
$data = $ret->getResources();

分页器

此模块提供了一个分页器辅助工具。

/* @var \Hermes\Api\Client $client */
$client = $this->getServiceLocator()->get('hermes');
/* @var \Hermes\Resource\Resource $ret */
$ret = $client->get('/album',['year' => 2015]);

// Returns how many items a page can have
$ret->getPaginator()->getPageSize();

// Returns how many pages the response has
$ret->getPaginator()->getPageCount();

// Returns how many items the response has (across all pages)
$ret->getPaginator()->getTotalItems();

// Returns the current page
$ret->getPaginator()->getPage();

您可以轻松地遍历页面

/* @var \Hermes\Api\Client $client */
$client = $this->getServiceLocator()->get('hermes');
$page = 1;
do {
    /* @var \Hermes\Resource\Resource $ret */
    $ret = $client->get('/album',[
        'year' => 2015,
        'page' => $page;
    ]);
    $data = $ret->getData();
    $page++;
} while ($ret->getPaginator()->hasMorePages());

您可以使用分页器与 Zend Framework 2 应用程序一起使用

$page = $this->getRequest()->getQuery('page', 1);
$sort = $this->getRequest()->getQuery('sort', 'name');
$order = $this->getRequest()->getQuery('order', 'asc');

$paginator = new \Laminas\Paginator\Paginator(new \Hermes\Paginator\ApiPaginator($client, $url, 'album', [
    'page'=>$page,
    'sort'=>$sort,
    'order' => $order,
]));
$paginator->setDefaultItemCountPerPage(25);
$paginator->setCurrentPageNumber($page);
$paginator->setPageRange($this->paginatorRange);

事件

客户端在请求之前(request.pre)和请求之后(request.post)触发事件,并且您可以将其附加到它们上。有关事件的更多信息,请参阅 zend-eventmanager

请求 ID

客户端自动为每个请求添加 X-Request-Id,但前提是没有先添加之前的 X-Request-Id。

您可以使用以下方法强制生成新的 ID

$client = $this->getServiceLocator()->get('hermes');
$client->addRequestId(); // Auto generared
$client->addRequestId('123abc');