bognerf/ rest-grabber-legacy
消耗 REST API(兼容 PHP 7.0 的回滚版本)
Requires
- php: >=7.0.7
- ext-json: *
- guzzlehttp/guzzle: ~6.0
- psr/simple-cache: ^1.0
- symfony/validator: ^3.4
Requires (Dev)
- phpunit/phpunit: ^6.0
- squizlabs/php_codesniffer: ^3.0
This package is auto-updated.
Last update: 2024-09-29 05:42:19 UTC
README
这是一个为与 PHP7.0 兼容而回滚的版本。在几乎所有情况下,您都应该使用 bognerf/rest-grabber
与 REST API 一起使用并确保 JSON 响应中存在并有效某些元素。
目录
通过 Composer
$ composer require bognerf/rest-grabber
用法
无验证或派生对象(值对象)生成的基本用法相当简单
use Bognerf\RestGrabber\Grabber;
use Bognerf\RestGrabber\Url;
$url = new Url('https://reqres.in/api/unknown/2');
$grabber = new Grabber($url);
$contents = $grabber->get()->grab()->data();
您将根据 https://reqres.in/api/unknown/2
的响应提供的 JSON 获得一个数组;
全局验证规则
您可以通过点分隔的键的数组来定义 JSON 响应中的必填值。此外,您还可以传递一个 约束 数组,给定键的值应与之匹配。RestGrabber 依赖于 Symfony 的约束库。
use Bognerf\RestGrabber\Grabber;
use Bognerf\RestGrabber\Url;
$url = new Url('https://reqres.in/api/users/2');
$grabber = new Grabber($url);
$grabber->getHandler()->setObligatoryFields([
'data' => [
new \Symfony\Component\Validator\Constraints\Count(['min'=>5])
],
'data.email' => [
new \Symfony\Component\Validator\Constraints\Email()
]
]);
$grabber->get()->grab();
上面的例子将查询 https://reqres.in/api/users/2
并确保根级元素 data
至少包含五个子元素。此外,如 data.email
所示,必须在 data
下存在一个 email
元素,其语法必须符合电子邮件地址。
值对象
RestGrabber 从我们 JSON 的某些子元素(甚至可能是根元素,如果您愿意的话)生成值对象。为了使其工作,我们必须将一个 Handler
传递给我们的 RestGrabber 实例。默认情况下,库提供了一个通用的处理器 Bognerf\RestGrabber\Handlers\PlainJson
。所有处理器都必须扩展抽象类 Bognerf\RestGrabber\Handler
。
如何使用它们
考虑以下 JSON 示例 1(从 https://reqres.in/api/unknown/ 获得)
{
"page": 1,
"per_page": 3,
"total": 12,
"total_pages": 4,
"data": [
{
"id": 1,
"name": "cerulean",
"year": 2000,
"color": "#98B2D1",
"pantone_value": "15-4020"
},
{
"id": 2,
"name": "fuchsia rose",
"year": 2001,
"color": "#C74375",
"pantone_value": "17-2031"
},
{
"id": 3,
"name": "true red",
"year": 2002,
"color": "#BF1932",
"pantone_value": "19-1664"
}
]
}
在 data 下有三个对象。使用 RestGrabber,您可以定义 data 作为值对象的根元素(也可以使用点表示法进行更深层次的嵌套,例如 data.sub-element),自动解析它们并从每个条目创建一个值对象。让我们看看
use Bognerf\RestGrabber\Grabber;
use Bognerf\RestGrabber\Url;
$url = new Url('https://reqres.in/api/unknown');
$grabber = new Grabber($url);
$grabber->getHandler()->addValueObjectsRoot([
'data' => []
]);
$grabber->get()->grab();
$valueObjects = $grabber->valueObjects('data');
我们依赖于内置的处理器 PlainJson
。现在 $valueObjects
是一个包含三个值对象的数组,可以使用以下方式使用
foreach ($valueObjects as $vo) {
echo $vo->getName() . PHP_EOL;
}
getName()
是一个魔法获取器函数。您可以通过 get
加上 元素的第一个字母大写
来检索值对象的任何元素。
此外,还有常见的魔法获取器
foreach ($valueObjects as $vo) {
echo $vo->color . PHP_EOL;
}
JSON 示例 2
您不仅限于只有一个值对象根,可以有多个。考虑我们稍作修改的 JSON
{
"page": 1,
"per_page": 3,
"total": 12,
"total_pages": 4,
"data": [
{
"id": 1,
"name": "cerulean",
"year": 2000,
"color": "#98B2D1",
"pantone_value": "15-4020"
},
{
"id": 2,
"name": "fuchsia rose",
"year": 2001,
"color": "#C74375",
"pantone_value": "17-2031"
},
{
"id": 3,
"name": "true red",
"year": 2002,
"color": "#BF1932",
"pantone_value": "19-1664"
}
],
"more-data": [
{
"id": 1,
"name": "Florian"
},
{
"id": 2,
"name": "Katharina"
}
]
}
如您所见,我们有多于一个潜在的值对象根,即 data 和 more-data。只需将 more-data 添加为第二个值对象根即可
use Bognerf\RestGrabber\Grabber;
use Bognerf\RestGrabber\Url;
$url = new Url('https://reqres.in/api/unknown');
$grabber = new Grabber($url);
$grabber->getHandler()->addValueObjectsRoot([
'data' => []
]);
$grabber->getHandler()->addValueObjectsRoot([
'more-data' => []
]);
$grabber->get()->grab();
$valueObjectsData = $grabber->getHandler()->valueObjects('data');
$valueObjectsMoreData = $grabber->getHandler()->valueObjects('more-data');
值对象验证规则
除了为整个 JSON 在全局范围内定义必填值之外,您还可以为每个值对象根中的元素定义验证器。再次使用我们位于 https://reqres.in/api/unknown
的 REST API,根级元素 data
包含多个对象,可以将其定义为值对象的根级。记住,值对象的根也使用点表示法。让我们看看如何实现这一点
use Bognerf\RestGrabber\Grabber;
use Bognerf\RestGrabber\Url;
$url = new Url('https://reqres.in/api/unknown');
$grabber = new Grabber($url);
$grabber->getHandler()->addValueObjectsRoot([
'data' => [
'id' => [],
'name' => [
new \Symfony\Component\Validator\Constraints\Length(['min' => 3, 'max' => 128])
],
'pantone_value' => [
new \Symfony\Component\Validator\Constraints\Regex([
'pattern' => '/^([0-9]){2}\-([0-9]){4}$/'
])
]
]
]);
$grabber->get()->grab();
$valueObjects = $grabber->valueObjects('data');
上面的示例会查询 https://reqres.in/api/unknown
并验证根级别元素 data
存在且包含至少两个元素。我们ValueObjects的根也将设置为 data
。在data中,每个元素必须有一个没有其他约束的 id
元素,以及一个 name
元素,其长度应至少为三个字符,最多为100个字符。最后,$grabber->valueObjects('data')
将返回一个ValueObjects数组,每个ValueObjects都经过检查以符合我们的约束。
自定义处理器
对于某些用例,创建自定义处理器是有意义的。例如,我们将使用Cloudflare内容分发网络的API cdnjs.com。
为了确保CDNJS的JSON响应包含我们依赖的所有关键元素,创建您的自定义处理器如下(请记住,在扩展基础处理器的构造函数时,不要忘记调用 parent::__construct()
)。
class CdnjsHandler extends \Bognerf\RestGrabber\Handler
{
public function __construct()
{
parent::__construct();
$this->obligatoryFields = [
'assets' => [],
'repository.type' => [
new \Symfony\Component\Validator\Constraints\EqualTo(['value' => 'git']),
],
];
$this->addValueObjectsRoot([
'assets' => [
'version' => [
new \Symfony\Component\Validator\Constraints\NotBlank(),
],
'files' => [
new \Symfony\Component\Validator\Constraints\Count(['min' => 2])
]
]
]);
}
}
有趣的部分是处理器定义了自己的必需元素和验证规则。我们要求JSON响应包含一个元素 assets 以及一个元素 repository.type,其值应该是 git。后者的存在是一个很好的点表示深层元素示例。比较来自 CDNJS 的实际JSON。
此外,位于 assets 下的集合或列表将构成我们的单个ValueObjects根,确保每个元素都包含一个 version 元素(必须存在且不为空、空或null)和一个 files 元素,它必须是一个包含至少两个元素的集合。
现在让我们使用我们新的自定义处理器。
use Bognerf\RestGrabber\Grabber;
use Bognerf\RestGrabber\Url;
$url = new Url('https://api.cdnjs.com/libraries/axios');
$grabber = new Grabber($url);
$grabber->setHandler(new CdnjsHandler());
$grabber->get()->grab();
$valueObjects = $grabber->valueObjects('assets');
dump($valueObjects);
与缓存一起工作
RestGrabber可以通过 RestGrabber::setCache()
接受一个 PSR-16 兼容的CacheInterface。我们将使用ZendCache,因此我们必须引入一些依赖项。
$ composer require zendframework/zend-cache
$ composer require zendframework/zend-serializer
但请记住,您可以使用任何PSR-16兼容的CacheInterface。它不一定是Zend的。
$storage = StorageFactory::factory([
'adapter' => [
'name' => 'filesystem',
'options' => [
'cache_dir' => '/tmp/rest-grabber',
],
],
'plugins' => [
'serializer',
],
]);
$cache = new SimpleCacheDecorator($storage);
$url = new Url('https://api.cdnjs.com/libraries/axios');
$grabber = new Grabber($url);
$grabber->setCache($cache);
echo ($grabber->isCached() ? "Hit":"Missed");
$grabber->setHandler(new \RestGrabberTestbed\Handlers\CdnjsHandler());
$grabber->get()->grab();
$valueObjects = $grabber->valueObjects('assets');
echo ($grabber->isCached() ? "Hit":"Missed");
测试
$ composer test
安全
如果您发现任何安全相关的问题,请通过电子邮件fb@florianbogner.de联系,而不是使用问题跟踪器。
致谢
- Florian Bogner(维护者)
许可
MIT许可(MIT)。有关更多信息,请参阅 许可文件。