lemric / batch-request
发送一个包含多个(批量)Symfony Request调用的单个HTTP请求。一旦所有操作完成,就会将汇总的响应返回给您,并关闭HTTP连接。
Requires
- php: >=8.1
- beberlei/assert: ^v3
- symfony/http-client: >=5.1
- symfony/http-kernel: >=5.1
- symfony/polyfill-php83: ^v1.30.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.60
- phpunit/phpunit: ^11.2.8
- rector/rector: ^1.2.2
- symfony/phpunit-bridge: >=5.1
Suggests
- symfony/rate-limiter: A "rate limiter" controls how frequently some event (e.g. an HTTP request or a login attempt) is allowed to happen.
README
安装
使用composer安装
composer require lemric/batch-request
批量请求
发送一个包含多个API调用的单个HTTP请求。独立操作并行处理,而依赖操作顺序处理。所有操作完成后,将汇总的响应返回给您,并关闭HTTP连接。
响应的顺序与请求中操作的顺序相匹配。您应根据此顺序处理响应,以确定哪些操作成功,哪些需要在后续操作中重试。
限制
要限制批处理中的请求数量,请使用symfony/rate-limiter
。批量请求由批次的symfony/rate-limiter请求配置限制。批处理中的每个调用都单独计算,以计算API调用限制。
批量请求
批量请求接收一个JSON对象,其中包含您的请求数组。它返回一个表示为JSON数组的逻辑HTTP响应数组。每个响应都有一个状态码、一个可选的头部数组和一个可选的正文(这是一个JSON编码的字符串)。
要发送批量请求,请向包含批处理参数的端点发送POST请求。
POST /batch
示例批量请求
在此示例中,我们将获取我们应用程序管理的两个页面信息。
格式化以提高可读性。
curl -X POST --location 'https://:8282/batch'
--header 'Content-Type: application/json'
--data '[
{
"method":"GET",
"relative_url":"url"
},
{
"method":"GET",
"relative_url":"url",
}
],
"include_headers": true'
一旦所有操作完成,就会发送一个包含每个操作结果的响应。因为返回的头部有时可能比实际的API响应大得多,您可能希望为了效率而删除它们。要包含头部,请删除include_headers参数或将它设置为true。
示例响应
正文字段包含一个字符串编码的JSON对象
[
{
"code": 200,
"body": "{
\"name\": \"Page A Name\",
\"id\": \"1\"
}"
},
{
"code": 200,
"body": "{
\"name\": \"Page B Name\",
\"id\": \"1\"
}"
}
]
复杂批量请求
可以将通常使用不同HTTP方法进行的操作组合成一个单独的批量请求。虽然GET和DELETE操作只能有relative_url和method字段,但POST和PUT操作可以有一个可选的body字段。正文应格式化为原始HTTP POST字符串,类似于URL查询字符串。
示例请求
以下示例在一个操作中删除对象并创建新对象
curl -X POST /batch
--header 'Content-Type: application/json'
--data '[
{
"method":"DELETE",
"relative_url":"url/{id}"
},
{
"method":"POST",
"relative_url":"url",
"body": {"id": "1", "message": "First post!"}
}
],
"include_headers": false'
错误
您请求的操作可能会失败。这可能是因为您没有执行请求操作所需的权限。响应类似于标准API,但封装在批量响应语法中
[
{ "code": 403,
"headers": [
{"name":"WWW-Authenticate", "value":"OAuth…"},
{"name":"Content-Type", "value":"text/javascript; charset=UTF-8"} ],
"body": "{\"error\":{\"type\":\"OAuthException\", … }}"
}
]
批量中的其他请求仍应成功完成,并以200状态码返回正常。
超时
如果批量中的所有请求完成需要太长时间,大或复杂的批量可能会超时。在这种情况下,结果是一个部分完成的批量。在部分完成的批量中,成功完成的请求将返回正常输出和状态码200。对未成功的请求的响应将为null。您可以重试任何失败的请求。
使用多个访问令牌
在一个批次请求中,单个请求可以指定自己的访问令牌作为查询字符串或表单提交参数。在这种情况下,顶级访问令牌被视为后备令牌,如果单个请求未明确指定访问令牌,则会使用该后备令牌。
如果您想使用多个不同的用户令牌查询API,或者一些调用需要使用应用程序访问令牌,这将非常有用。
即使每个单个请求都包含自己的令牌,也必须包含访问令牌作为顶级参数。
上传二进制数据
您可以在批次调用中上传多个二进制项目。为此,您必须将所有二进制项目作为multipart/mime附件添加到请求中,并且每个操作必须使用操作中的attached_files属性引用其二进制项目。attached_files属性可以接受逗号分隔的附件名称列表作为其值。
以下示例展示了如何在单个批次调用中上传2张照片
curl
-F 'access_token=…' \
-F 'batch=[{"method":"POST","relative_url":"me/photos","body":"message=My cat photo","attached_files":"file1"},{"method":"POST","relative_url":"me/photos","body":"message=My dog photo","attached_files":"file2"},]' \
-F 'file1=@cat.gif' \
-F 'file2=@dog.jpg' \
/batch
Symfony示例
控制器
<?php namespace App\Controller; use Lemric\BatchRequest\BatchRequest; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\{Request, Response}; use Symfony\Component\Routing\Annotation\Route; class DefaultController extends AbstractController { #[Route('/batch', name: 'batch')] public function indexAction(Request $request, BatchRequest $batchRequest): Response { return $batchRequest->handle($request); } }
services.yaml
Lemric\BatchRequest\BatchRequest: ~ bind: <-- Only if used syfmony/rate-limiter $rateLimiterFactory: '@limiter.authenticated_api' <-- Use proper configuration service name