Example below uses one-legged OAuth authentication to communicate with end-points. To do that cURL is being used for command and Guzzle client used for class file.


cURL commands version


These do exactly what Guzzle class example below does.


getAccountStatus()


curl -v -X GET -H 'Authorization: OAuth oauth_consumer_key="6481-6163-0300",oauth_signature_method="HMAC-SHA1",oauth_nonce="722971702f951d91aa2690e18ef14aca",oauth_timestamp="1425917962",oauth_version="1.0",oauth_signature="TsoWZK68V3%2F3Kt9lBBdA26g1z50%3D"' 'http://api.sandbox.wetesting.com/1/account/status.json'

getProducts()


curl -v -X GET -H 'Authorization: OAuth oauth_consumer_key="6481-6163-0300",oauth_signature_method="HMAC-SHA1",oauth_nonce="bb8b3cf9c3c8694d0dc8bee59ab10548",oauth_timestamp="1425923436",oauth_version="1.0",oauth_signature="CY5IobHKrfTdejD4R46m2oZdD9Y%3D"' 'http://api.sandbox.wetesting.com/1/products/filter.json?sku=SKU-3'

curl -v -X GET -H 'Authorization: OAuth oauth_consumer_key="6481-6163-0300",oauth_signature_method="HMAC-SHA1",oauth_nonce="80414a842e9fbd8eb93c2122ab7b8833",oauth_timestamp="1425921594",oauth_version="1.0",oauth_signature="BiyMdb7LkxB%2B%2Fzb1JvGqhuXhR5g%3D"' 'http://api.sandbox.wetesting.com/1/products/filter.json?is_active=1&limit=2&page=1'

updateSingleProduct()


curl -v -X PATCH -H 'Authorization: OAuth oauth_consumer_key="6481-6163-0300",oauth_signature_method="HMAC-SHA1",oauth_nonce="eb5600671f3361076715a87c8ed4e61b",oauth_timestamp="1425923870",oauth_version="1.0",oauth_signature="eF3okhQcdTwcI3cW235B6%2FOJ2LU%3D"' -H "Content-Type:application/json" -d '{"sku":"D30145","title":"DicotaMultiSlight","base_price":43.59,"stock":9,"is_active":true}' 'http://api.sandbox.wetesting.com/1/products.json'

Guzzle class version


namespace My\Bundle\ApiBundle\Util;

use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Stream\Stream;
use OAuth;

class ApiClient
{
const RESPONSE_FORMAT = 'json';
const OAUTH_VERSION = '1.0';
const METHOD_POST = 'POST';
const METHOD_PUT = 'PUT';
const METHOD_PATCH = 'PATCH';
const METHOD_GET = 'GET';
const METHOD_DELETE = 'DELETE';

/**
* @var string
*/
private $apiKey;

/**
* @var string
*/
private $apiSecret;

/**
* @var string
*/
private $apiDomain;

/**
* @var string
*/
private $apiProtocol;

public function __construct($apiKey, $apiSecret, $apiDomain = 'api.domain.com', $useHttps = false)
{
$this->apiKey = $apiKey;
$this->apiSecret = $apiSecret;
$this->apiDomain = $apiDomain;
$this->apiProtocol = ($useHttps === true) ? 'https' : 'http';
}

public function getAccountStatus()
{
$method = self::METHOD_GET;
$request = $this->prepareRequest(
$this->getUri('/1/account/status.'.self::RESPONSE_FORMAT),
$method
);

return $this->call(
$request['requestParams']['uri'],
$method,
$request['authHeader']
);
}

public function getProducts($isActive, $limit, $page, $sku = null)
{
$params = [];

if (isset($isActive)) {
$params['is_active'] = $isActive;
}

if ($sku) {
$params['sku'] = $sku;
} else {
$params['limit'] = $limit;
$params['page'] = $page;
}

$method = self::METHOD_GET;
$request = $this->prepareRequest(
$this->getUri('/1/products/filter.'.self::RESPONSE_FORMAT, $params),
$method
);

return $this->call(
$request['requestParams']['uri'],
$method,
$request['authHeader']
);
}

public function updateSingleProduct($sku, $title, $isActive, $basePrice, $stock)
{
$params = [];
$params['sku'] = $sku;
$params['title'] = $title;
$params['is_active'] = $isActive;
$params['base_price'] = $basePrice;
$params['stock'] = $stock;

$method = self::METHOD_PATCH;
$request = $this->prepareRequest(
$this->getUri('/1/products.'.self::RESPONSE_FORMAT),
$method
);

return $this->call(
$request['requestParams']['uri'],
$method,
$request['authHeader'],
$params
);
}

/**
* @param string $uri
* @param array $params
*
* @return string
*/
private function getUri($uri, array $params = [])
{
return sprintf(
'%s://%s%s?%s',
$this->apiProtocol,
$this->apiDomain,
$uri,
http_build_query($params)
);
}

/**
* @param string $uri
* @param string $method
* @param null|array|string $params
*
* @return array
*/
private function prepareRequest($uri, $method, $params = null)
{
$requestParams = $this->getRequestParams($uri, $params);
$oauth = $this->getOauth($requestParams);
$authHeader = $oauth->getRequestHeader($method, $requestParams['uri'], $requestParams['params']);

return [
'requestParams' => $requestParams,
'authHeader' => $authHeader
];
}

/**
* @param string $uri
* @param null|array|string $params
*
* @return array
*/
private function getRequestParams($uri, $params = null)
{
return [
'consumerKey' => $this->apiKey,
'consumerSecret' => $this->apiSecret,
'nonce' => md5(uniqid(mt_rand(), true)),
'timestamp' => time(),
'oauthVersion' => self::OAUTH_VERSION,
'uri' => $uri,
'params' => is_array($params) ? $params : []
];
}

/**
* @param array $requestParams
*
* @return OAuth
*/
private function getOauth(array $requestParams)
{
$oauth = new OAuth($requestParams['consumerKey'], $requestParams['consumerSecret']);
$oauth->setNonce($requestParams['nonce']);
$oauth->setTimestamp($requestParams['timestamp']);
$oauth->setVersion($requestParams['oauthVersion']);

return $oauth;
}

/**
* @param string $uri
* @param string $method
* @param string $authHeader
* @param array $payload
*
* @return array
* @throws Exception
*/
private function call($uri, $method, $authHeader, array $payload = [])
{
try {
$client = new Client();
$request = $client->createRequest($method, $uri);
$request->addHeader('Authorization', $authHeader);
$request->addHeader('Content-Type', 'application/json');
$request->setBody(Stream::factory(json_encode($payload)));
$response = $client->send($request);
} catch (RequestException $e) {
$message = $e->hasResponse()
? $e->getResponse()
: 'An unknown error occurred while trying to process your request.';

throw new Exception($message);
}

return json_decode($response->getBody(), true);
}
}