Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterator final docs #523

Merged
merged 5 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 30 additions & 22 deletions CBP_UPGRADE_GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# OBP to CBP Upgrade guide

TODO version requirement, how to bump.

## Useful links

* [This README](./README.md#pagination)
* [Pagination](https://developer.zendesk.com/api-reference/introduction/pagination)
* [Ticketing sorting](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#sorting)
- [This README](./README.md#pagination)
- [Pagination](https://developer.zendesk.com/api-reference/introduction/pagination)
- [Ticketing sorting](https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#sorting)

## CBP Basics

Expand All @@ -16,47 +14,57 @@ When using OBP, if you request page 100, the DB will need to index all records t

CBP works based on cursors, so when ordering by `id` with page size 10, if the last item on your page has id 111, the response includes a link to the next page (`links.next`) which can be used to request the next 10 elements after id 111, and only the requested rows are indexed before fetching. When in the response `meta.has_more` is `false` you are done.

## The new iterator

The best way to upgrade your app to support CBP is to use the iterator we provide. Please refer to the [README](./README.md#iterator-recommended).

**Note**: The iterator will automatically convert the param `page_size` to work with CBP.

The iterator is available in `v3.0`, which you can download with:

```sh
composer update zendesk/zendesk_api_client_php
```

## Debugging

Please refer to the [README](./README.md#debugging).

## API calls

Note the query parameters change in these two URL examples:

* OBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort_order=desc&sort_by=updated_at&per_page=2
* CBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort=-updated_at&page[size]=2
- OBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort_order=desc&sort_by=updated_at&per_page=2
- CBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort=-updated_at&page[size]=2

### CBP ordering

When moving from OBP to CBP sorting params change as well:
When moving from OBP to CBP sorting params _may_ change as well:

* From: `?sort_name=updated_at&sort_order=desc`
* To: `sort=-updated_at`
- From: `?sort_name=updated_at&sort_order=desc`
- To: `sort=-updated_at`

However, the list of **attributes you can sort by might also change** with the pagination type:

https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#sorting

* OBP: `"assignee", "assignee.name", "created_at", "group", "id", "locale", "requester"`
* CBP: `"updated_at", "id", "status"`
- OBP: `"assignee", "assignee.name", "created_at", "group", "id", "locale", "requester"`
- CBP: `"updated_at", "id", "status"`

Example:

* OBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort_order=desc&sort_by=assignee.name&per_page=2 `HTTP 200`, works
* CBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort=assignee.name&page[size]=2 `HTTP 400`
- OBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort_order=desc&sort_by=assignee.name&per_page=2 `HTTP 200`, works
- CBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort=assignee.name&page[size]=2 `HTTP 400`

```json
{
"error": "InvalidPaginationParameter",
"description": "sort is not valid"
"error": "InvalidPaginationParameter",
"description": "sort is not valid"
}
```

If this is your situation, **you will need to change the sorting order** to a supported one.

## The new iterator

The best way to upgrade your app to support CBP is to use the iterator we provide. Please refer to the [README](./README.md#iterator-recommended).

**Note**: The iterator will automatically convert these parameters to work with CBP: `page_size, sort_by, sort_order`.

## Parallel requests

If you are fetching multiple pages in parallel using OBP, you need to refactor to a serial execution, and fetch one page at a time.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ foreach ($iterator as $ticket) {
* Refer to the docs for details, including allowed sort fields
* Combine everything: `$params = ['page[size]' => 2, 'sort' => 'updated_at', 'extra' => 'param'];`

**Note**: Refer to the documentation for the correct params for sorting with the pagination type you're using.

##### Iterator API call response

The latest response is exposed in the iterator at `$iterator->latestResponse()`. This could come handy for debugging.
Expand Down Expand Up @@ -275,11 +277,30 @@ speed up the process and would make sure that everybody follows the community's

### Debugging

#### REPL

To help would be contributors, we've added a REPL tool. It is a simple wrapper for [psysh](http://psysh.org) and symfony's console.
On your terminal, run `bin/console <subdomain> <email> <api token>`. This would automatically create an instance of `Zendesk\API\HttpClient` on $client variable.
After that you would be able to enter any valid php statement. The goal of the tool is to speed up the process in which developers
can experiment on the code base.

#### HTTP client print API calls

You can print a line with details about every API call with:

```php
$client = new ZendeskAPI($subdomain);
$client->log_api_calls = true;
```

#### HTTP client debug

You can inspect this object for info about requests and responses:

```php
$client->getDebug();
```

## Copyright and license

Copyright 2013-present Zendesk
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"license": "Apache-2.0",
"homepage": "https://github.com/zendesk/zendesk_api_client_php",
"require": {
"php": ">=5.5.0",
"php": ">=7.4.0",
"guzzlehttp/guzzle": "^6.0 || ^7.0",
"guzzlehttp/psr7": "^1.7 || ^2.0",
"mmucklo/inflect": "0.3.*"
Expand Down
4 changes: 3 additions & 1 deletion src/Zendesk/API/Http.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ public static function send(
if ($client->getAuth()) {
list ($request, $requestOptions) = $client->getAuth()->prepareRequest($request, $requestOptions);
}
// echo "\nExternal API call: " . $request->getMethod() . " " . $request->getUri() . "\n";
if ($client->log_api_calls) {
echo "\nZendesk\API\Http: " . $request->getMethod() . " " . $request->getUri() . "\n";
}
$response = $client->guzzle->send($request, $requestOptions);
} catch (RequestException $e) {
$requestException = RequestException::create($e->getRequest(), $e->getResponse(), $e);
Expand Down
8 changes: 8 additions & 0 deletions src/Zendesk/API/HttpClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,14 @@ class HttpClient
*/
protected $debug;

/**
* Whether or not to print every API call details right before execution
*
* E.G.: Zendesk\API\Http: GET https://my_company.zendesk.com/api/v2/tickets.json
*
* @var boolean
*/
public $log_api_calls = false;
/**
* @var \GuzzleHttp\Client
*/
Expand Down
20 changes: 1 addition & 19 deletions src/Zendesk/API/Traits/Utility/Pagination/CbpStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,12 @@ public function shouldGetPage($position) {

public function params()
{
$result = array_merge($this->params, $this->paginationParams(), $this->sortParams());
$result = array_merge($this->params, $this->paginationParams());
$result = $this->unsetObpParams($result);

return $result;
}

/**
* The params that are needed to ordering in CBP (eg: ["sort" => "-age"])
* If OBP params are passed, they are converted to CBP
*
* OBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort_order=desc&sort_by=updated_at&per_page=2
* CBP: https://{subdomain}.zendesk.com/api/v2/tickets?sort=-updated_at&page[size]=2
*
* @return array Params with proper CBP sorting order
*/
private function sortParams()
{
if (isset($this->params['sort_by']) && !isset($this->params['sort'])) {
$direction = (isset($this->params['sort_order']) && strtolower($this->params['sort_order']) === 'desc') ? '-' : '';
return array_merge($this->params, ['sort' => $direction . $this->params['sort_by']]);
} else {
return [];
}
}
/**
* The params that are needed to for pagination (eg: ["page[size]" => "100"])
* If OBP params are passed, they are converted to CBP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,23 +125,6 @@ public function testFetchesCbpWithParams()
], $mockTickets->params);
}

public function testCorrectsParamsToCbp()
{
$mockTickets = new MockResource('tickets', [
[['id' => 1], ['id' => 2]],
[['id' => 3], ['id' => 4]]
]);
$strategy = new CbpStrategy('tickets', ['per_page' => 2, 'sort_by' => 'id', 'sort_order' => 'desc']);
$iterator = new PaginationIterator($mockTickets, $strategy, 'findAll');

iterator_to_array($iterator);

$this->assertEquals([
'sort' => '-id',
'page[size]' => 2, 'page[after]' => 'cursor_for_next_page'
], $mockTickets->params);
}

public function testFetchesSinglePageWithParams()
{
$resultsKey = 'results';
Expand Down
Loading