Server-side PHP wrapper for simple retrievals from Germania's JSON APIs with Cache support.
$ composer require germania-kg/jsonapi-client
The JsonApiClient requires a Guzzle Client which will perform the API requests. You may either bring your own Guzzle instance or use the GuzzleFactory, which is useful for API endpoints that require a “bearer” Access token.
<?php
use Germania\JsonApiClient\GuzzleFactory;
// Have your Web API endpoint and Access token at hand
$api = "https://api.example.com/"
$token = "manymanyletters";
// Setup a Guzzle Client that will ask the Web API
$guzzle = (new GuzzleFactory)( $api, $token);
The JsonApiClient requires the above Guzzle Client as well as a PSR-6 Cache ItemPool. It optionally accepts a PSR-3 Logger and/or a PSR-3 Loglevel name for errors.
<?php
use Germania\JsonApiClient\JsonApiClient;
use Germania\JsonApiClient\GuzzleFactory;
use GuzzleHttp\Client;
$guzzle = new Client( ... );
$guzzle = (new GuzzleFactory)( $api, $token);
$cache = new \Stash\Pool( ... );
$logger = new \Monolog\Logger( ... );
$api_client = new JsonApiClient($guzzle, $cache );
$api_client = new JsonApiClient($guzzle, $cache, $logger );
$api_client = new JsonApiClient($guzzle, $cache, $logger, "alert" );
Error loglevel: Loglevel name to use when Guzzle fails. Defaults to error.
$api_client->error_loglevel = "error";
Request method: This library is built for GET and is not intended or tested for POST, DELETE and such.
$api_client->request_method = "GET";
Cache life time: The cache lifetime will be taken from the API response and fallback to this value:
$api_client->cache_lifetime_default = 3600;
Results are stored in the PSR-6 cache passed to the JsonApiClient constructor, using a cache key to look up the results next time.
This cache key contains a fast-to-compute sha256 hash of the authorization header. The downside is, your auth tokens are vulnerable to hash collision attacks, when two different string produce the same hash.
The auth token hopefully has a baked-in lifetime. Once this lifetime is reached, the auth token is worthless anyway. And, when an attacker has file access to your cache, he will have all results, regardless if he has your auth tokens or not.
Security tips:
- Consider to pass an “Always-empty-cache” or one with very short lifetime, such as Stash's Ephemeral driver.
- Store your cache securely. This is not responsibility of this library.
- Clean your items cache often. This is not responsibility of this library.
The JsonApiClient class is callable; invoking with a URL path and an optional filter values array returns an ArrayIterator with the documents provided by the API.
Caching: The results are cached in the given PSR-6 Cache Item Pool. The cache item TTL depends on the Cache-Control: max-age=SECONDS
header that came along with the response to the Guzzle Client request. The default TTL is 3600 seconds.
$items = $downloads_client("some/url/path");
foreach( $items as $item):
print_r( $item );
endforeach;
The print_r( $item )
could reveal something like this:
Array (
[company] => ACME Corp.
[brand] => ACME's Best
[title] => ACME Super Thingy
...
)
To narrow down the results, both the all and latest methods accept an array with filter values. The fiter values may contain multiple values, separated with comma.
Think of the filter array items as WHERE … AND…
clauses, and comma-separated values as 'a' OR 'b'
$filters = array(
'company' => "ACME",
'category' => "brochure",
'language' => "en"
);
$items = $downloads_client("some/url/path", $filters);
Any error or exception during the ask-cache / request / response / results-building phases will first be logged to the PSR-3 Logger passed to the constrcutor. The error caught will be re-thrown as JsonApiClientExceptionInterface exception instances.
<?php
use Germania\JsonApiClient\JsonApiClientExceptionInterface;
use Germania\JsonApiClient\{
JsonApiClientCacheException,
JsonApiClientRequestException,
JsonApiClientResponseException,
JsonApiClientResultsException
};
Before the request is actually sent, the Cache ItemPool will be asked. In case of any error, a JsonApiClientCacheException will be thrown This class implements JsonApiClientExceptionInterface
and extends \RuntimeException
.
When the JsonApiClient catches a Guzzle RequestException or TransferExceptions, i.e. something wrong with the request or on the server, a JsonApiClientRequestException will be thrown. This class implements JsonApiClientExceptionInterface
and extends \RuntimeException
.
The response is expected to be a valid JsonAPI response. Whenever the response can't be decoded to a useful array, a JsonApiClientResponseException will be thrown. This class implements JsonApiClientExceptionInterface
and extends \UnexpectedValueException
.
When there's a problem building the result array, or writing to the cache, a JsonApiClientResultsException will be thrown. This class implements JsonApiClientExceptionInterface
and extends \RuntimeException
.
$ git clone https://github.com/GermaniaKG/jsonapi-client-php.git
$ cd jsonapi-client-php
$ composer install
Copy phpunit.xml.dist
to phpunit.xml
and adapt the API_BASE_URL and AUTH_TOKEN environment variables. Then run PhpUnit like this:
$ composer test
# or
$ vendor/bin/phpunit