Как создать пагинацию в API Shopify Rest с помощью php
Я создал curl на php для использования API-интерфейса shopify. Теперь я хочу создать в нем разбиение на страницы.
Как создать?
Link: "<https://{shop}.myshopify.com/admin/api/{version}/products.json?page_info={page_info}&limit={limit}>; rel={next}, <https://{shop}.myshopify.com/admin/api/{version}/products.json?page_info={page_info}&limit={limit}>; rel={previous}"
Как использовать ссылку?
Спасибо
3 ответа
Функция ниже может вам помочь. для получения данных с помощью API в Php/Laravel
public function request($method,$url,$param = []){
$client = new \GuzzleHttp\Client();
$url = 'https://'.$this->username.':'.$this->password.'@'.$this->domain.'/admin/api/2019-10/'.$url;
$parameters = [
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json'
]
];
if(!empty($param)){ $parameters['json'] = $param;}
$response = $client->request($method, $url,$parameters);
$responseHeaders = $response->getHeaders();
$tokenType = 'next';
if(array_key_exists('Link',$responseHeaders)){
$link = $responseHeaders['Link'][0];
$tokenType = strpos($link,'rel="next') !== false ? "next" : "previous";
$tobeReplace = ["<",">",'rel="next"',";",'rel="previous"'];
$tobeReplaceWith = ["","","",""];
parse_str(parse_url(str_replace($tobeReplace,$tobeReplaceWith,$link),PHP_URL_QUERY),$op);
$pageToken = trim($op['page_info']);
}
$rateLimit = explode('/', $responseHeaders["X-Shopify-Shop-Api-Call-Limit"][0]);
$usedLimitPercentage = (100*$rateLimit[0])/$rateLimit[1];
if($usedLimitPercentage > 95){sleep(5);}
$responseBody = json_decode($response->getBody(),true);
$r['resource'] = (is_array($responseBody) && count($responseBody) > 0) ? array_shift($responseBody) : $responseBody;
$r[$tokenType]['page_token'] = isset($pageToken) ? $pageToken : null;
return $r;
}
Пример использования этой функции
$product_ids = [];
$nextPageToken = null;
do{
$response = $shop->request('get','products.json?limit=250&page_info='.$nextPageToken);
foreach($response['resource'] as $product){
array_push($product_ids, $product['id']);
}
$nextPageToken = $response['next']['page_token'] ?? null;
}while($nextPageToken != null);
Если вы хотите использовать api graphQL в php / laravel, то сообщение ниже может вам помочь
Начиная с версии API 2019-07 вам действительно нужно использовать разбиение на страницы на основе курсора.
Сначала сделайте обычный вызов API, включите ответ заголовка.
Тогда в заголовке ответа вы увидите ссылку: ... с rel next или previous.
Извлеките page_info, а затем сделайте еще один вызов с помощью page_info.
Первый вызов выглядит примерно так:
https://...:...@xyz.myshopify.com/admin/api/2019-10/products.json?limit=2&published_status=published
Тогда второй звонок
https://...:...@xyz.myshopify.com/admin/api/2019-10/products.json?limit=2&page_info=asdfas1321asdf3as1f651saf61s3f1x32v1akjhfasdj
Когда вы делаете второй вызов, удалите все фильтры, поскольку фильтры будут применяться с первого вызова.
Кстати: если вы тестируете в браузере из-за того, что ссылка находится в угловых скобках, она будет скрыта, поэтому просто просмотрите исходный код в своей среде разработчика.
Ссылка: https://help.shopify.com/en/api/guides/paginated-rest-results
private $shop_url = '';
private $shop_user = '';
private $shop_password = '';
function __construct($shop) {
$this->shop_url = $shop->url;
$this->shop_user = $shop->user;
$this->shop_password = $shop->userpas;
$this->syncShopifyOrder($shop);
}
private function getOrderRequest($url){
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', $url, [
'auth' => [$this->shop_user, $this->shop_password]
]);
if($response->getStatusCode() !== 200){
throw new OrderSyncException('Connection problem!');
}
$data = [];
$paginate_links = $response->getHeader('Link');
if($paginate_links){
$page_link = $paginate_links[0];
$links_arr = explode(",", $page_link);
if($links_arr){
$tobeReplace = ["<",">",'rel="next"',";",'rel="previous"'];
$tobeReplaceWith = ["","","",""];
foreach ($links_arr as $link) {
$link_type = strpos($link, 'rel="next') !== false ? "next" : "previous";
parse_str(parse_url(str_replace($tobeReplace, $tobeReplaceWith, $link), PHP_URL_QUERY), $op);
$data[$link_type] = trim($op['page_info']);
}
}
}
$order_data = $response->getBody()->getContents();
$data['all_orders'] = (json_decode($order_data))->orders;
return $data;
}
// Shopify Orders
private function syncShopifyOrder($shop)
{
$count = 0;
try{
if($shop){
$nextPageToken = null;
do{
$param = ($nextPageToken)? '&page_info='.$nextPageToken : '&status=any&fulfillment_status=any&order=created_at asc&created_at_min=2020-08-10T13:30:33+02:00';
$url = $this->shop_url . 'admin/api/2020-01/orders.json?limit=250'.$param;
$data = $this->getOrderRequest($url);
$all_orders = $data['all_orders'];
$nextPageToken = isset($data['next']) ? $data['next'] : null;
if($all_orders){
$count += count((array) $all_orders);
$this->bulkorderInsertShopify($shop, $all_orders);
}
}while($nextPageToken);
}else{
throw new OrderSyncException('You have not configured shop!');
}
$this->syncSuccessReport($shop, $count);
}catch(OrderSyncException $e) {
$this->syncErrorReport($shop, $count, $e->getMessage());
}catch(\Exception $e) {
$this->syncErrorReportAdmin($shop, $count, $e);
}
}