it-bens/api-caller

用于执行带有限制和偏移量响应序列的API请求的包装器。

dev-master 2022-05-14 11:37 UTC

This package is auto-updated.

Last update: 2024-09-14 16:18:57 UTC


README

Maintenance Status CI Status codecov

API调用者能为我做什么?

许多商业API实现了一些分页或结果限制。但有时从API获取所有可用记录(受查询参数限制)是必要的。这就是API调用者的作用。

而不是手动执行多个请求,API调用者会这样做。它支持带有限制和偏移量参数的API以及带有分页令牌的API。为了保持使用灵活性,API调用者将实际的API使用留给了开发者。它只去掉了在循环中执行API请求的重复逻辑,直到收集到所需的结果。

如何安装此包?

此包可以通过Composer安装

composer require it-bens/api-caller

它至少需要PHP 8。它还针对PHP 8.1进行了测试。

使用示例是什么样的?

首先,您必须确定您要调用的API是否使用限制和偏移量或分页令牌。在两种情况下,都必须创建一个实现 ApiCallerInterface 的特定API调用者。

可以将实际请求所需的参数数组传递给包装器请求方法。

带有限制和偏移量的API

use ITB\ApiCaller\WithLimitOffset\ApiCallerInterface;
use ITB\ApiCaller\WithLimitOffset\ApiCallerResponse;

class SpecificApiCaller implements ApiCallerInterface
{
    private const MAX_RESULTS_PER_REQUEST = 10;

    public function __construct() {}

    public function doRequest(int $limit, int $offset, array $parameters): ApiCallerResponse
    {
        $items = doSomeApiCall([
            'limit' => $limit,
            'offset' => $offset,
            'greeting1' => $parameters['greeting1'],
            'greeting2' => $parameters['greeting2']
        ]);
        return new ApiCallerResponse($items);
    }

    /**
     * @return int
     */
    public function getResultsPerRequest(): int
    {
        return self::MAX_RESULTS_PER_REQUEST;
    }
}

API调用者与 ApiCallerWrapper 一起使用。它是一个只包含一个方法的特质。

use ITB\ApiCaller\WithLimitOffset\ApiCallerWrapper;

class SomeService
{
    use ApiCallerWrapper;

    public function someMethode()
    {
        $apiCaller = new SpecificApiCaller('This is the way!', 1337);
        
        $items = $this->request($apiCaller, null, 10, ['greeting1' => 'Ahoi', 'greeting2' => 'Hi']);
        // OR:
        $items = $this->request($apiCaller, 100, 10, ['greeting1' => 'Ahoi', 'greeting2' => 'Hi']);
        
        // ...
    }
}

带有分页令牌的API

带有分页令牌的 ApiCallerInterface 需要两个实现API调用的方法。一个用于初始请求,将限制和偏移量传递给实际API(用于生成页面),以及一个用于处理带有分页令牌的请求的方法。

use ITB\ApiCaller\WithPageToken\ApiCallerInterface;
use ITB\ApiCaller\WithPageToken\ApiCallerResponse;

class AnotherSpecificApiCaller implements ApiCallerInterface
{
    private const MAX_RESULTS_PER_REQUEST = 10;

    public function __construct() {}

    public function doFollowUpRequest(string $pageToken, array $parameters): ApiCallerResponse
    {
        $response = doSomeApiCall([
            'pageToken' => $pageToken,
            'greeting1' => $parameters['greeting1'],
            'greeting2' => $parameters['greeting2']
        ]);

        return new ApiCallerResponse($response['items'], $response['nextPageToken']);
    }

    public function doInitialRequest(?int $limit, int $offset, array $parameters): ApiCallerResponse
    {
        $limit = (null === $limit || $limit > self::MAX_RESULTS_PER_REQUEST) ? self::MAX_RESULTS_PER_REQUEST : $limit;

        $response = doSomeApiCall([
            'limit' => $limit,
            'offset' => $offset,
            'greeting1' => $parameters['greeting1'],
            'greeting2' => $parameters['greeting2']
        ]);

        return new ApiCallerResponse($response['items'], $response['nextPageToken']);
    }
    
    // ...
}

API调用者与带有限制和偏移量的API调用者类似。

use ITB\ApiCaller\WithPageToken\ApiCallerWrapper;

class SomeService
{
    use ApiCallerWrapper;

    public function someMethode()
    {
        $apiCaller = new AnotherSpecificApiCaller('This is the way!', 1337);
        
        $items = $this->request($apiCaller, null, 10, ['greeting1' => 'Ahoi', 'greeting2' => 'Hi']);
        // OR:
        $items = $this->request($apiCaller, 100, 10, ['greeting1' => 'Ahoi', 'greeting2' => 'Hi']);
        
        // ...
    }
}

如何测试此包?

该包提供了PHPUnit测试。在本地环境中,可以通过docker执行测试和静态代码分析。

./development.sh docker-build
docker-compose run --rm -T phpunit php vendor/bin/phpunit --configuration phpunit.xml tests
docker-compose run --rm -T phpunit php -d memory_limit=2G vendor/bin/phpstan analyse src tests --level 8

PHPUnit测试和PHPStan的静态代码分析也在GitHub actions上的任何push或PR上执行。GitHub Actions CI使用所有支持的PHP版本和所有支持的Symfony版本运行。

贡献

我非常高兴看到软件开发社区像我一样热爱开源!♥

这就是为什么我欣赏每个打开的问题(最好是建设性的)和每个提供其他或甚至更好代码到这个包的pull request。

你们都是令人惊叹的!