Difference between revisions of "6CS028 Workshop - Web Services"

From mi-linux
Jump to navigationJump to search
 
(36 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[[Main Page]] >> [[CP3207|Web Application Development]] >> [[Web Application Developpment - Workbook|Workbook]] >> Week 07
+
[[Main Page]] >> [[6CS028|Advanced Web Development]] >> [[6CS028 - Workbook|Workbook]] >> Week 05
  
There are so many exciting APIs available on the web that it is impossible to cover them all here… so let’s have a look at a known REST example and a known SOAP example:
+
'''Important''': this is a CodeIgniter example, but it is easily adaptable to Laravel.
 
 
* REST - The Wikipedia API
 
* SOAP - The Google Search API
 
* A challenge for you!
 
  
 
== REST - The Wikipedia API ==
 
== REST - The Wikipedia API ==
  
All features shown on [http://en.wikipedia.org/w/api.php this page] should be working, but the API is still in active development, and may change at any time. Make sure to monitor their mailing list for any updates.
+
Let’s simply find all all the Wikipedia pages that link to my website [http://www.bdtheque.com www.bdtheque.com] :o)
  
Let’s simply find all all the Wikipedia pages that link to my website www.bdtheque.com :o)
+
With REST, it's all about calling the right URL, passing in the right parameters... here is the URL we need:
  
With REST, it's all about calling the right URL, passing in the right parameters... here is the URL we need:
+
[http://en.wikipedia.org/w/api.php?action=query&list=exturlusage&format=xml&euquery=www.bdtheque.com Click me!] (look at the address bar)
  
[http://en.wikipedia.org/w/api.php?action=query&list=exturlusage&format=xml&euquery=www.bdtheque.com Click me!]
+
Note that we are passing the following parameters:
 +
* action = query
 +
* list = exturlusage (the service we are requesting)
 +
* format = xml (the format of the response)
 +
* euquery = www.bdtheque.com (the parameter required for this service)
  
 
If you click on the URL, your browser simply display the XML data (try looking at the page's source code).
 
If you click on the URL, your browser simply display the XML data (try looking at the page's source code).
  
So our PHP code looks very much like the code we used to access an RSS feed. Indeed in both cases we are accessing a remote XML file!
+
=== The controller ===
  
 +
Create a new '''Apis.php''' controller:
 
<pre>
 
<pre>
<?
+
<?php
  
  $url = "http://en.wikipedia.org/w/api.php?"
+
namespace App\Controllers;
        ."action=query&"
 
        ."list=exturlusage&"
 
        ."format=xml&"
 
        ."euquery=www.bdtheque.com";
 
         
 
  // Get raw data
 
  $response = file_get_contents($url);
 
 
 
  // Convert raw data to object
 
  $xml = simplexml_load_string($response);
 
 
  // Loop through data and display
 
  foreach($xml->query->exturlusage->eu as $link)
 
  {
 
    echo "<H1>{$link['title']}</H1><P>Links to: {$link['url']}</P>";
 
  } 
 
  
?>
+
use App\Models\NewsModel;
</pre>
 
  
And that’s it! Your page should now be displaying all the Wikipedia pages that link to my website www.bdtheque.com.
+
class Apis extends BaseController
 +
{
 +
public function wikipedia()
 +
{
 +
// Since 2010 a user agent is required
 +
ini_set('user_agent', 'University of Wolverhampton');
  
== A SOAP example: Google Search ==
+
$website = "www.bdtheque.com";
  
Accessing SOAP APIs is just as simple. But first you need to download the NuSOAP library. It will do a lot of the work for you.
+
$url = "http://en.wikipedia.org/w/api.php?"
 +
."action=query&"
 +
."list=exturlusage&"
 +
."eulimit=500&"
 +
."format=xml&"
 +
."euquery=".$website;
 +
 
 +
// Get data from URL and store in object
 +
$data['links'] = simplexml_load_file($url);
 +
$data['title'] = "Wikipedia API";
  
* [http://sourceforge.net/projects/nusoap/files/ http://sourceforge.net/projects/nusoap/files/]
+
echo view('templates/header', $data);
 
+
echo view('apis/wikipedia', $data);
Simply unzip the archive in your web pages’ folder.
+
echo view('templates/footer', $data);
 +
}
 +
}
 +
</pre>
 +
Please note:
 +
* We are using XML in this example, but you could try using JSON.
 +
* Once we have the XML data, but simply pass it on to a new view (see below).
  
Now the code… well nothing too difficult here:
+
=== The view ===
* First you include the library you have just downloaded
 
* Then you create a SOAP client object and set its encoding
 
* Then you prepare your SOAP request and send it.
 
* The response is a multidimensional array. You can use the print_r command to display it fully if you wish.
 
  
 +
Next, create a new view (Views/apis/wikipedia.php):
 
<pre>
 
<pre>
<?
+
<?php foreach($links->query->exturlusage->eu as $link):?>
  require("nusoap/lib/nusoap.php");
+
    <h2><?=$link['title']?></h2>
 
+
    <p>Links to: <a href='<?=$link['url']?>'><?=$link['url']?></a></p>
  // What we are searching for
+
     <p>pageid: <?=$link['pageid']?></p>
  $search = "Alix Bergeret";
+
<?php endforeach?>  
 
 
  // Create soap client
 
  $client = new soapclient("http://api.google.com/GoogleSearch.wsdl", true);
 
 
 
  // Set encoding
 
  $client->soap_defencoding = 'UTF-8';
 
 
 
  // Prepare request
 
  $request = array(
 
'key'=>'4B0KufpQFHJxhAxzua0tR11ElLNrHRJ6',
 
'q'=>$search,
 
'start'=>0,
 
'maxResults'=>5,
 
'filter'=>false,
 
'restrict'=>'',
 
'safeSearch'=>true,
 
'lr'=>'',
 
'ie'=>'',
 
'oe'=>'',
 
);
 
 
 
  // Send request and read response
 
  $result = $client->call('doGoogleSearch', $request, "urn:GoogleSearch", "urn:GoogleSearch");
 
 
 
  // Loop through array and display
 
  foreach($result['resultElements'] as $one_result)
 
  {
 
    print "<h1>{$one_result['title']}</h1>";
 
     print "<p>{$one_result['snippet']}</p>";
 
  }
 
?>
 
 
</pre>
 
</pre>
 +
Please note:
 +
* It's a simple foreach loop, that displays all items.
 +
* Here is my working example: [https://mi-linux.wlv.ac.uk/~in9352/ci4/public/apis/wikipedia https://mi-linux.wlv.ac.uk/~in9352/ci4/public/apis/wikipedia]
  
All done!
+
== REST - Authentication via CURL ==
 
 
== A challenge for you! ==
 
 
 
The Amazon [https://affiliate-program.amazon.co.uk/gp/advertising/api/detail/main.html Product Advertising API] is one of the most exciting ones available, as it gives you free access to the huge Amazon catalogue, as well as some cool functionalities (searches, similar products, customer reviews etc)
 
 
 
Unfortunately it became a lot harder to access it on 15th August 2009, as Amazon now requires all requests to be signed and time stamped.
 
 
 
I have spent a couple of hours trying to get the top selling books from Amazon.com via a REST request, but failed miserably. I get the following error message:
 
 
 
“xxx is not a valid value for Signature. Please change this value and retry your request.”
 
 
 
I have included my code so far (you will need to get your own account, with a public and a private key), and a few useful links.
 
 
 
Have a go! The first student to get it to work will win my gratitude and uttermost respect, as well as a free copy of a brand new book entitled “Web 2.0 architectures”. Exciting stuff! (where’s the geeky smiley on this thing?)
 
  
Useful links:
+
Some APIs will ask you to authenticate, by providing specific HTTP headers. This can be achieved using the [https://www.php.net/manual/en/intro.curl.php cURL PHP library], which "allows you to connect and communicate to many different types of servers with many different types of protocols."
  
* [https://affiliate-program.amazon.co.uk/gp/advertising/api/detail/main.html API's home page]
+
=== Reed.co.uk example ===
* [http://docs.amazonwebservices.com/AWSECommerceService/2009-10-01/DG/ Full documentation]
+
The Reed API located [https://www.reed.co.uk/developers/jobseeker here] explains that "You will need to include your api key for all requests in a basic authentication http header as the username, leaving the password empty."
* [http://docs.amazonwebservices.com/AWSECommerceService/2009-10-01/DG/index.html?HMACAuth_ItemsRequired.html Documentation - Authentication Parameters]
 
* [http://docs.amazonwebservices.com/AWSECommerceService/2009-10-01/DG/index.html?rest-signature.html Documentation - Example REST Requests]
 
 
 
My code so far:
 
  
 +
You can achieve this in PHP like this:
 
<pre>
 
<pre>
<?
+
<?php
  
  $secret_key = 'Your own secret key here';
+
// Set connection details
 +
$login = 'PUT YOUR REED API KEY HERE';
 +
$password = '';
 +
$url = 'https://www.reed.co.uk/api/1.0/search?keywords=laravel&location=wolverhampton&distancefromlocation=15';
  
  //---------------------------------------------------------------
+
// Create CURL object with options
  // List of parameters
+
$ch = curl_init();
  //---------------------------------------------------------------
+
curl_setopt($ch, CURLOPT_URL,$url);
  $param_string = "AWSAccessKeyId=Your own public key here"
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
                ."&BrowseNodeId=283155"
+
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
                ."&Operation=BrowseNodeLookup"
+
curl_setopt($ch, CURLOPT_USERPWD, "$login:$password");
                ."&ResponseGroup=TopSellers"
 
                ."&Service=AWSECommerceService"
 
                ."&Timestamp=".urlencode(date("Y-m-d\TH:i:s\Z"))
 
                ."&Version=".urlencode('2009-01-06');
 
  
  //---------------------------------------------------------------
+
// Make CURL call, and convert result to JSON object
  // Build signature
+
$jobs = curl_exec($ch);
  //---------------------------------------------------------------
+
$jobs = json_decode($jobs);
  $signature = "GET\n";
+
curl_close($ch);
  $signature.= "webservices.amazon.com\n";
 
  $signature.= "/onca/xml\n";
 
  $signature.= $param_string;
 
  
  //---------------------------------------------------------------
+
// Display results
  // Hash and url encode signature
+
foreach($jobs->results as $job) {
  //---------------------------------------------------------------
+
print($job->jobTitle . "<br>");
  $signature = hash_hmac('sha256', $signature, $secret_key);
+
}
  $signature = urlencode($signature);
+
</pre>
 
 
  //---------------------------------------------------------------
 
  // Add signature to parameters
 
  //---------------------------------------------------------------
 
  $param_string = $param_string."&Signature=".$signature;
 
 
 
  //---------------------------------------------------------------
 
  // Build URL
 
  //---------------------------------------------------------------
 
  $url = "http://webservices.amazon.com/onca/xml?$param_string";
 
  
  //---------------------------------------------------------------
+
Here is my working example
  // Get raw data
+
* [https://mi-linux.wlv.ac.uk/~in9352/apis/reed.php https://mi-linux.wlv.ac.uk/~in9352/apis/reed.php]
  //---------------------------------------------------------------
 
  $response = file_get_contents($url);
 
  print("$response");
 
  
  //---------------------------------------------------------------
+
== Going further: the OpenWeatherMap API ==
  // Convert raw data to object
+
Adapt the example above to obtain current weather data for Wolverhampton, from the OpenWeatherMap API:
  //---------------------------------------------------------------
+
* [https://openweathermap.org/current https://openweathermap.org/current]
  $xml = simplexml_load_string($response);
+
* You'll need to register for a free API Key
+
* Like the Wikipedia API, the OpenWeatherMap API supports both XML and JSON.
  // Browse object and display book titles
 
  foreach($xml->BrowseNodes->BrowseNode->TopSellers->TopSeller as $book)
 
  {
 
    echo $book->Title."<br>";
 
  }
 
 
 
?>
 
</pre>
 

Latest revision as of 14:31, 21 February 2023

Main Page >> Advanced Web Development >> Workbook >> Week 05

Important: this is a CodeIgniter example, but it is easily adaptable to Laravel.

REST - The Wikipedia API

Let’s simply find all all the Wikipedia pages that link to my website www.bdtheque.com :o)

With REST, it's all about calling the right URL, passing in the right parameters... here is the URL we need:

Click me! (look at the address bar)

Note that we are passing the following parameters:

  • action = query
  • list = exturlusage (the service we are requesting)
  • format = xml (the format of the response)
  • euquery = www.bdtheque.com (the parameter required for this service)

If you click on the URL, your browser simply display the XML data (try looking at the page's source code).

The controller

Create a new Apis.php controller:

<?php

namespace App\Controllers;

use App\Models\NewsModel;

class Apis extends BaseController
{
	public function wikipedia()
	{
		// Since 2010 a user agent is required
		ini_set('user_agent', 'University of Wolverhampton');

		$website = "www.bdtheque.com";

		$url = "http://en.wikipedia.org/w/api.php?"
			."action=query&"
			."list=exturlusage&"
			."eulimit=500&"
			."format=xml&"
			."euquery=".$website;
		  
		// Get data from URL and store in object
		$data['links'] = simplexml_load_file($url);
		$data['title'] = "Wikipedia API";

		echo view('templates/header', $data);
		echo view('apis/wikipedia', $data);
		echo view('templates/footer', $data);		
	}
}

Please note:

  • We are using XML in this example, but you could try using JSON.
  • Once we have the XML data, but simply pass it on to a new view (see below).

The view

Next, create a new view (Views/apis/wikipedia.php):

<?php foreach($links->query->exturlusage->eu as $link):?>
    <h2><?=$link['title']?></h2>
    <p>Links to: <a href='<?=$link['url']?>'><?=$link['url']?></a></p>
    <p>pageid: <?=$link['pageid']?></p>
<?php endforeach?> 

Please note:

REST - Authentication via CURL

Some APIs will ask you to authenticate, by providing specific HTTP headers. This can be achieved using the cURL PHP library, which "allows you to connect and communicate to many different types of servers with many different types of protocols."

Reed.co.uk example

The Reed API located here explains that "You will need to include your api key for all requests in a basic authentication http header as the username, leaving the password empty."

You can achieve this in PHP like this:

<?php

// Set connection details
$login = 'PUT YOUR REED API KEY HERE';
$password = '';
$url = 'https://www.reed.co.uk/api/1.0/search?keywords=laravel&location=wolverhampton&distancefromlocation=15';

// Create CURL object with options
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$login:$password");

// Make CURL call, and convert result to JSON object
$jobs = curl_exec($ch);
$jobs = json_decode($jobs);
curl_close($ch);  

// Display results
foreach($jobs->results as $job) {
	print($job->jobTitle . "<br>");
}

Here is my working example

Going further: the OpenWeatherMap API

Adapt the example above to obtain current weather data for Wolverhampton, from the OpenWeatherMap API: