Skip to content

MINOR Add structured Limit objects for rate limiting API, deprecate getRateLimits() #733

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

Merged
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
20 changes: 14 additions & 6 deletions doc/rate_limits.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
## Rate Limit API
[Back to the navigation](README.md)

Get Rate Limit
Wraps [GitHub Rate Limit API](http://developer.github.com/v3/rate_limit/).
Get rate limit wrappers from [GitHub Rate Limit API](http://developer.github.com/v3/rate_limit/).

#### Get All Rate Limits.
#### Get All Rate Limits

```php
$rateLimits = $client->api('rate_limit')->getRateLimits();
/** @var \Github\Api\RateLimit\RateLimitResource[] $rateLimits
$rateLimits = $client->api('rate_limit')->getLimits();
```

#### Get Core Rate Limit

```php
$coreLimit = $client->api('rate_limit')->getCoreLimit();
$coreLimit = $client->api('rate_limit')->getResource('core')->getLimit();
$remaining = $client->api('rate_limit')->getResource('core')->getRemaining();
$reset = $client->api('rate_limit')->getResource('core')->getReset();
```

#### Get Search Rate Limit

```php
$searchLimit = $client->api('rate_limit')->getSearchLimit();
$searchLimit = $client->api('rate_limit')->getResource('search')->getLimit();
```

#### Get GraphQL Rate Limit

```php
$searchLimit = $client->api('rate_limit')->getResource('graphql')->getLimit();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an resource for graphql included in the rest api result? I can't find it in the docs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you're right it's not in there - not sure why. It is in the results of the existing API result from using this SDK though.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes indeed I've just checked it with a curl call. So let's keep it in the docs!

```
75 changes: 67 additions & 8 deletions lib/Github/Api/RateLimit.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Github\Api;

use Github\Api\RateLimit\RateLimitResource;

/**
* Get rate limits.
*
Expand All @@ -12,36 +14,93 @@
class RateLimit extends AbstractApi
{
/**
* Get rate limits.
* @var RateLimitResource[]
*/
protected $resources = [];

/**
* Get rate limits data in an array.
*
* @deprecated since 2.11.0 Use `->getResources()` instead
*
* @return array
*/
public function getRateLimits()
{
return $this->get('/rate_limit');
return $this->fetchLimits();
}

/**
* Gets the rate limit resource objects.
*
* @return RateLimitResource[]
*/
public function getResources()
{
$this->fetchLimits();

return $this->resources;
}

/**
* Returns a rate limit resource object by the given name.
*
* @param string $name
*
* @return RateLimitResource|false
*/
public function getResource($name)
{
// Fetch once per instance
if (empty($this->resources)) {
$this->fetchLimits();
}

if (!isset($this->resources[$name])) {
return false;
}

return $this->resources[$name];
}

/**
* Returns the data directly from the GitHub API endpoint.
*
* @return array
*/
protected function fetchLimits()
{
$result = $this->get('/rate_limit') ?: [];

// Assemble Limit instances
foreach ($result['resources'] as $resourceName => $resource) {
$this->resources[$resourceName] = new RateLimitResource($resourceName, $resource);
}

return $result;
}

/**
* Get core rate limit.
*
* @deprecated since 2.11.0 Use `->getResource('core')->getLimit()` instead
*
* @return int
*/
public function getCoreLimit()
{
$response = $this->getRateLimits();

return $response['resources']['core']['limit'];
return $this->getResource('core')->getLimit();
}

/**
* Get search rate limit.
*
* @deprecated since 2.11.0 Use `->getResource('core')->getLimit()` instead
*
* @return int
*/
public function getSearchLimit()
{
$response = $this->getRateLimits();

return $response['resources']['search']['limit'];
return $this->getResource('search')->getLimit();
}
}
61 changes: 61 additions & 0 deletions lib/Github/Api/RateLimit/RateLimitResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Github\Api\RateLimit;

/**
* Represents the data block for a GitHub rate limit response, grouped by a name.
*/
class RateLimitResource
{
/**
* @param string $name
* @param array $data
*/
public function __construct($name, array $data)
{
$this->name = $name;
$this->limit = $data['limit'];
$this->remaining = $data['remaining'];
$this->reset = $data['reset'];
}

/**
* The name of the Limit, e.g. "core", "graphql", "search".
*
* @return string
*/
public function getName()
{
return $this->name;
}

/**
* The rate limit amount.
*
* @return int
*/
public function getLimit()
{
return $this->limit;
}

/**
* Number of requests remaining in time period before hitting the rate limit.
*
* @return int
*/
public function getRemaining()
{
return $this->remaining;
}

/**
* Timestamp for when the rate limit will be reset.
*
* @return int
*/
public function getReset()
{
return $this->reset;
}
}
99 changes: 79 additions & 20 deletions test/Github/Tests/Api/RateLimitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,94 @@

namespace Github\Tests\Api;

use Github\Api\RateLimit;

class RateLimitTest extends TestCase
{
/**
* @test
* Used for common assertions in each test.
*
* @var array
*/
public function shouldReturnRateLimitArray()
{
$expectedArray = [
'resources' => [
'core' => [
'limit' => 5000,
'remaining' => 4999,
'reset' => 1372700873,
],
'search' => [
'limit' => 30,
'remaining' => 18,
'reset' => 1372697452,
],
protected $expectedArray = [
'resources' => [
'core' => [
'limit' => 5000,
'remaining' => 4999,
'reset' => 1372700873,
],
'search' => [
'limit' => 30,
'remaining' => 18,
'reset' => 1372697452,
],
'graphql' => [
'limit' => 5000,
'remaining' => 4030,
'reset' => 1372697452,
],
];
],
];

/**
* @var RateLimit
*/
protected $api;

/**
* Used to construct common expectations for the API input data in each unit test.
*
* {@inheritdoc}
*/
protected function setUp()
{
parent::setUp();

$api = $this->getApiMock();
$api->expects($this->once())
$this->api = $this->getApiMock();
$this->api->expects($this->once())
->method('get')
->with('/rate_limit')
->will($this->returnValue($expectedArray));
->will($this->returnValue($this->expectedArray));
}

$this->assertEquals($expectedArray, $api->getRateLimits());
/**
* @test
*/
public function shouldReturnRateLimitArray()
{
$this->assertSame($this->expectedArray, $this->api->getRateLimits());
}

/**
* @test
*/
public function shouldReturnArrayOfLimitInstances()
{
$this->assertContainsOnlyInstancesOf(RateLimit\RateLimitResource::class, $this->api->getResources());
}

/**
* @test
*/
public function shouldReturnRemainingGraphQLRequests()
{
$this->assertSame(4030, $this->api->getResource('graphql')->getRemaining());
}

/**
* @test
*/
public function shouldReturnResetForSearch()
{
$this->assertSame(1372697452, $this->api->getResource('search')->getReset());
}

/**
* @test
*/
public function shouldReturnFalseWhenResourceIsNotFound()
{
$this->assertFalse($this->api->getResource('non-exitent'));
}

/**
Expand Down
14 changes: 14 additions & 0 deletions test/Github/Tests/Integration/RateLimitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Github\Tests\Integration;

use Github\Api\RateLimit\RateLimitResource;

/**
* @group integration
*/
Expand All @@ -17,4 +19,16 @@ public function shouldRetrievedRateLimits()
$this->assertArrayHasKey('resources', $response);
$this->assertArraySubset(['resources' => ['core' => ['limit' => 60]]], $response);
}

/**
* @test
*/
public function shouldRetrieveRateLimitsAndReturnLimitInstances()
{
$response = $this->client->api('rate_limit')->getLimits();

$this->assertInternalType('array', $response);
$this->assertContainsOnlyInstancesOf(RateLimitResource::class, $response);
$this->assertEquals(60, $response->getLimit('core')->getLimit());
}
}