-
Notifications
You must be signed in to change notification settings - Fork 23
Extending The Datasource
tenebrousedge edited this page Dec 26, 2012
·
2 revisions
In the Database Config page you may have noticed a suggestion that using static OAuth 2.0 credentials was a bad idea. You may also have noticed that expired tokens are refreshed when they are retrieved from storage. The ApisSource datasource provides no methods for detecting token expiration. Additionally, it is highly unlikely that any methods could be implemented, as the behavior of the API at that point is not defined. Most APIs will return a 403 error, but this might also be returned for other reasons.
The other big reason for extending the APIs datasource is to implement the
When using static OAuth 2.0 credentials, it is highly likely that you will end up using an expired token, whereas most other implementations should be able to avoid this. It will therefore be imperative that you detect this error and recover from it.
This guide can only offer a general guideline to how token refreshing might be implemented. Do not use the example; write your own version. That goes double if you're using static OAuth 2.0 credentials.
<?php
#filename: Plugin/Example/Model/Datasource/ExampleSource.php
class ExampleSource extends ApisSource {
public function afterRequest(Model $model, HttpSocketResponse $response){
if($response->code == 403 && !(strpos($response->body, 'Expired Token') === false)){
$id = AuthComponent::user('id');
$model->authorize($model, $id);
return $this->request($model);
}
return parent::afterRequest($model, $response);
}
beforeRequest()
callback. Changing the behavior of decode()
and the logging functions may also be advisable.
#filename: Plugin/Example/Model/Datasource/ExampleSource.php
<?php
App::uses('ApisSource', 'Copula.Model/Datasource');
class ExampleSource extends ApisSource {
// Key => Values substitutions in the uri-path right before the request is made. Scans uri-path for :keyname
public $tokens = array();
// Last minute tweaks
public function beforeRequest(Model $model) {
$model->request['header']['x-li-format'] = $this->options['format'];
return $model->request;
}
}
It should be noted that the beforeRequest()
callback should return the request array. Similarly, afterRequest()
should return the (possibly processed) results.