mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
223 lines
6.5 KiB
Markdown
223 lines
6.5 KiB
Markdown
# Restful Service
|
|
|
|
## Introduction
|
|
|
|
`[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)
|
|
returned from the web service. Further it supports caching of the response, and you can customize the cache interval.
|
|
|
|
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).
|
|
|
|
|
|
## Examples
|
|
|
|
### Creating a new RestfulObject
|
|
|
|
:::php
|
|
//example for using RestfulService to connect and retrive latest twitter status of an user.
|
|
$twitter = new RestfulService("http://twitter.com/statuses/user_timeline/user.xml", $cache_expiry );
|
|
$params = array('count' => 1);
|
|
$twitter->setQueryString($params);
|
|
$conn = $twitter->request();
|
|
$msgs = $twitter->getValues($conn, "status");
|
|
|
|
|
|
### Extending to a new class
|
|
|
|
:::php
|
|
//example for extending RestfulService
|
|
class FlickrService extends RestfulService {
|
|
|
|
public function __construct($expiry=NULL){
|
|
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');
|
|
|
|
$peopleXML = $service->request('/people');
|
|
$people = $service->getValues($peopleXML, 'user');
|
|
|
|
// ...
|
|
|
|
$taskXML = $service->request('/tasks');
|
|
$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
|
|
<entries>
|
|
<entry id='12'>Sally</entry>
|
|
<entry id='15'>Ted</entry>
|
|
<entry id='30'>Matt</entry>
|
|
<entry id='22'>John</entry>
|
|
</entries>
|
|
|
|
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
|
|
<media:guide>
|
|
<media:entry id="2030">video</media:entry>
|
|
</media:guide>
|
|
|
|
to get the value of entry node with the namespace media, use:
|
|
|
|
:::php
|
|
$this->searchValue($response, "//media:guide/media:entry")
|
|
|
|
|
|
|
|
## Best Practices
|
|
|
|
|
|
### Handling Errors
|
|
|
|
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
|
|
|
|
:::php
|
|
// 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;
|
|
}
|
|
|
|
|
|
|
|
If you want to bypass error handling on your sub-classes you could define that in the constructor.
|
|
|
|
:::php
|
|
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
|
|
}
|
|
|
|
|
|
### 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,
|
|
CURLOPT_CONNECTTIMEOUT => 10,
|
|
));
|
|
```
|
|
|
|
|
|
#### 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);
|
|
|
|
```
|
|
|
|
## Other Uses
|
|
|
|
### How to use `[api:RestfulService]` to easily embed an RSS feed
|
|
|
|
`[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
|
|
// 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;
|
|
}
|
|
|
|
|
|
Put something like this code in `themes/<your-theme>/templates/Layout/HomePage.ss`:
|
|
|
|
:::ss
|
|
<h3>My Latest Del.icio.us Links</h3>
|
|
<ul>
|
|
$RestfulLinks(http://del.icio.us/rss/elijahlofgren)
|
|
</ul>
|
|
|
|
|
|
## API Documentation
|
|
`[api:RestfulService]`
|