2011-02-07 07:48:44 +01:00
# Restful Service
## Introduction
2014-03-20 04:00:13 +01:00
`[api:RestfulService]` uses the php curl library, enabling connections to remote web services which support a REST interface and consuming those web services. (Examples: [Flickr ](http://www.flickr.com/services/api/ ), [Youtube ](http://code.google.com/apis/youtube/overview.html ), Amazon and etc). `[api:RestfulService]` can parse the XML response (sorry no JSON support)
2011-02-07 07:48:44 +01:00
returned from the web service. Further it supports caching of the response, and you can customize the cache interval.
2011-03-08 22:05:51 +01:00
To gain the functionality you can either create a new `[api:RestfulService]` object or create a class extending the
RestfulService (see [flickrservice ](http://silverstripe.org/flickr-module/ ) and
[youtubeservice ](http://silverstripe.org/youtube-gallery-module/ ) modules).
2011-02-07 07:48:44 +01:00
## Examples
### Creating a new RestfulObject
:::php
2014-04-23 16:31:22 +02:00
//example for using RestfulService to connect and retrive latest twitter status of an user.
2011-02-07 07:48:44 +01:00
$twitter = new RestfulService("http://twitter.com/statuses/user_timeline/user.xml", $cache_expiry );
2014-04-23 16:31:22 +02:00
$params = array('count' => 1);
$twitter->setQueryString($params);
$conn = $twitter->request();
$msgs = $twitter->getValues($conn, "status");
2011-02-07 07:48:44 +01:00
### Extending to a new class
:::php
//example for extending RestfulService
class FlickrService extends RestfulService {
2012-01-30 23:13:42 +01:00
public function __construct($expiry=NULL){
2011-02-07 07:48:44 +01:00
parent::__construct('http://www.flickr.com/services/rest/', $expiry);
$this->checkErrors = true;
}
......
### Multiple requests by using the $subURL argument on connect()
:::php
// Set up REST service
$service = new RestfulService("http://example.harvestapp.com");
$service->basicAuth('username', 'password');
$service->httpHeader('Accept: application/xml');
$service->httpHeader('Content-Type: application/xml');
2014-04-23 16:31:22 +02:00
$peopleXML = $service->request('/people');
2011-02-07 07:48:44 +01:00
$people = $service->getValues($peopleXML, 'user');
2012-10-02 11:38:16 +02:00
// ...
2011-02-07 07:48:44 +01:00
2014-04-23 16:31:22 +02:00
$taskXML = $service->request('/tasks');
2011-02-07 07:48:44 +01:00
$tasks = $service->getValues($taskXML, 'task');
## Features
### Caching
To set the cache interval you can pass it as the 2nd argument to constructor.
:::php
new RestfulService("http://twitter.com/statuses/user_timeline/user.xml", 3600 );
### Getting Values & Attributes
You can traverse throught document tree to get the values or attribute of a particular node.
for example you can traverse
:::xml
2014-04-23 16:31:22 +02:00
< entries >
2011-02-07 07:48:44 +01:00
< entry id = '12' > Sally< / entry >
< entry id = '15' > Ted< / entry >
< entry id = '30' > Matt< / entry >
< entry id = '22' > John< / entry >
2014-04-23 16:31:22 +02:00
< / entries >
2011-02-07 07:48:44 +01:00
to extract the id attributes of the entries use:
:::php
$this->getAttributes($xml, "entries", "entry") //will return all attributes of each entry node
to extract the values (the names) of the entries use:
:::php
$this->getValues($xml, "entries", "entry") //will return all values of each entry node
### Searching for Values & Attributes
If you don't know the exact position of dom tree where the node will appear you can use xpath to search for the
node.Recommended for retrieving values of namespaced nodes.
:::xml
2014-04-23 16:31:22 +02:00
< media:guide >
2011-02-07 07:48:44 +01:00
< media:entry id = "2030" > video< / media:entry >
2014-04-23 16:31:22 +02:00
< / media:guide >
2011-02-07 07:48:44 +01:00
to get the value of entry node with the namespace media, use:
:::php
2014-04-23 16:31:22 +02:00
$this->searchValue($response, "//media:guide/media:entry")
2011-02-07 07:48:44 +01:00
## Best Practices
### Handling Errors
2011-03-08 22:05:51 +01:00
If the web service returned an error (for example, API key not available or inadequate parameters) `[api:RestfulService]`
could delgate the error handling to it's descendant class. To handle the errors define a function called errorCatch
2011-02-07 07:48:44 +01:00
:::php
2014-04-23 16:31:22 +02:00
// This will raise Youtube API specific error messages (if any).
public function errorCatch($response){
$err_msg = $response;
if(strpos($err_msg, '< ') === false) {
user_error("YouTube Service Error : $err_msg", E_USER_ERROR);
}
return $response;
}
2011-02-07 07:48:44 +01:00
If you want to bypass error handling on your sub-classes you could define that in the constructor.
:::php
2014-04-23 16:31:22 +02:00
public function __construct($expiry=NULL){
parent::__construct('http://www.flickr.com/services/rest/', $expiry);
$this->checkErrors = false; //Set checkErrors to false to bypass error checking
}
2011-02-07 07:48:44 +01:00
2014-05-07 11:12:08 +02:00
### Setting cURL options
Restful service uses cURL to make requests. There are various settings that can be defined on the cURL
request (see http://www.php.net/manual/en/function.curl-setopt.php) via the curl_setopts function.
There are two ways to define these for `RestfulService` ; they can be global settings or per request settings.
It is important to note that your cURL options will be applied LAST and so take preference over any default
values that `RestfulService` sets (such as `CURLOPT_RETURNTRANSFER` ) so changing these options may result
in unexpected behaviour or broken functionality.
#### Global cURL settings
To set global cURL settings you can update the `RestfulService` config via the Config system or YAML.
Here is an example to increase the HTTP Timeout globally. Insert this in your `_config.php` file:
```php
Config::inst()->update('RestfulService', 'default_curl_options', array(
CURLOPT_DNS_CACHE_TIMEOUT => 3600,
2014-05-07 13:06:44 +02:00
CURLOPT_CONNECTTIMEOUT => 10,
2014-05-07 11:12:08 +02:00
));
```
#### Per request settings
When making a request using `RestfulService` one can also pass through an array of cURL options in the last
parameter in `RestfulService::request()` .
For example:
```php
//cURL options
$curlOptions = array(
CURLOPT_UNRESTRICTED_AUTH => true,
);
$service = new RestfulService('http://example.com/');
$service->request('service.json', 'GET', null, null, $curlOptions);
```
2011-02-07 07:48:44 +01:00
## Other Uses
2011-03-08 22:05:51 +01:00
### How to use `[api:RestfulService]` to easily embed an RSS feed
2011-02-07 07:48:44 +01:00
`[api:RestfulService]` can be used to easily embed an RSS feed (since it's also an xml response) from a site
such as del.icio.us
Put something like this code in mysite/code/Page.php inside class Page_Controller
:::php
2014-04-23 16:31:22 +02:00
// Accepts an RSS feed URL and outputs a list of links from it
public function RestfulLinks($url){
$service = new RestfulService($url);
$request = $service->request();
$body = $request->getBody();
$items = $service->getValues($body,"channel","item");
$output = '';
foreach($items as $item) {
// Fix quote encoding
$description = str_replace('& quot;', '" ', $item->description);
$output .= "< li >< a href = \"{$item- > link}\">{$item->title}</ a >< br /> {$description}</ li > ";
}
return $output;
}
2011-02-07 07:48:44 +01:00
2012-06-27 16:09:21 +02:00
Put something like this code in `themes/<your-theme>/templates/Layout/HomePage.ss` :
2011-02-07 07:48:44 +01:00
:::ss
< h3 > My Latest Del.icio.us Links< / h3 >
< ul >
$RestfulLinks(http://del.icio.us/rss/elijahlofgren)
< / ul >
## API Documentation
2013-11-11 22:50:27 +01:00
`[api:RestfulService]`