Worksheet Weeks 8-9: REST

This week you are going to develop a REST Web Service which allows the client to query, delete or update the HitTastic! database. Remember that the concept of REST is to provide one URL per web resource, which can be retrieved, altered or deleted depending on the HTTP method used to access the URL.

The URL you are going to work with operates on a particular hit from HitTastic!, e.g.

http://edward/hittastic/1009
This URL represents hit 1009 in HitTastic! :

Questions

Writing the REST web service

  1. Copy and paste this code. This is some template code for a HitTastic! REST Web Service. Notice how we are using an if statement to examine the request method (GET, DELETE or PUT) and act accordingly.
    <?php
    
    $a = $_GET["id"];
    
    $conn  = mysql_connect("localhost","dftitutorials", "password");
    mysql_select_db ("dftitutorials");
    
    if($a<=0)
    {
        // What should we do if $a is invalid (0 or less)?
    }
    
    // Check that the ID exists
    $result=mysql_query("select * from hits where ID=$a");
    if(mysql_num_rows($result)==0)
    {
        // What should we do if the ID doesn't exist? 
    }
    
    if ($_SERVER["REQUEST_METHOD"]=="GET")
    {
        // retrieve the song
    }
    elseif ($_SERVER["REQUEST_METHOD"]=="DELETE")
    {
        // delete the song
    }
    elseif ($_SERVER["REQUEST_METHOD"]=="PUT")
    {
        // update the song
    }
    
    mysql_close($conn);
    ?>
    
  2. Add code to restserver.php to handle a "GET" request. This just performs a lookup of the selected song:
    $result = mysql_query("select * from hits where ID='$a'");
    $row = mysql_fetch_array($result);
    echo " <hit> ";
    echo " <title> $row[song] </title> ";
    echo " <artist> $row[artist] </title> ";
    echo " <year> $row[year] </year> ";
    echo " <quantity> $row[quantity] </quantity> ";
    echo " <price> $row[price] </price> ";
    echo " </hit> ";
    
  3. Add code to handle a "DELETE" request:
    mysql_query("delete from hits where ID='$a'"); 
  4. Fill in the code to handle the ID being invalid (less than 0) or non- existent. Use appropriate HTTP error codes in each case to inform the client of the error. Here is how you send a custom HTTP code back to the client:
    header("HTTP/1.1 200 OK");
    
    You will want to substitute 200 OK with an appropriate error code.
  5. Transfer to your space on Edward and test the Web Service out using a URL such as:
    http://edward.solent.ac.uk/~pjones/restserver.php?id=1009
    Since the default method is GET, when you enter the Web Service URL in your browser you will get the XML corresponding to the hit with the supplied ID.
  6. When everyone has got this far, I will transfer each of your files to a directory on the server which allows you to use a REST style URL e.g.
    http://edward.solent.ac.uk/students/pjones/hittastic/song/1009

Writing a client to the web service, to test it

Web services would normally be called from a client script or application, for example with cURL. The only problem is that using unusual HTTP methods, such as PUT or DELETE, from cURL is very difficult. Because of this, I have provided a PHP script which makes calling a REST Web Service easier, saving you from having to use cURL directly, as the code to handle the different types of request (GET, PUT, DELETE, POST) can get very complicated! (lack of client support for PUT and DELETE is an important disadvantage of developing REST web services). I have emailed this script to you.. To use it in a script, you need to add the line:

include('call_web_service.php');
at the top of your script.

With this script, to call any Web Service all you need to do is:

$result = call_web_service( URL, method, data);
e.g.:
$result = call_web_service
("http://edward.solent.ac.uk/students/pjones/hittastic/song/1009", 
"GET"); 
would send a GET request to the specified URL, causing the data for hit 1009 to be retrieved, and
$result = call_web_service
("http://edward.solent.ac.uk/students/pjones/hittastic/song/1009", 
"DELETE"); 
would send a DELETE request to the URL, causing hit 1009 to be deleted.

$result contains the result returned from the web service. It contains two fields:

  1. Make a copy of your existing IndieWorld client script (the one which parses the XML data using SAX or EasySAX) so that it reads in a song ID from a form, rather than an artist, and sends a GET request to your REST web service. Save it as iw_rest_GET.php
  2. Connect your modified IndieWorld client script so that it connects to this form:
    <html>
    <head>
    <style type='text/css'>
    body { background-color: black; color: white }
    </style>
    </head>
    <body>
    <h1>IndieWorld - Test REST client</h1>
    <form method="post" action="iw_rest_GET.php">
    ID of song:
    <input name="id" />
    <input type='submit' value='Go!' />
    </form>
    </body>
    </html>
    
  3. Imagine IndieWorld have the rights to delete songs from HitTastic! Write a script which sends a DELETE request to the HitTastic! REST web service to delete a song with a given ID. Make sure that you act upon any error codes returned by the web service using an if statement, e.g.
    if ($response["code"]==401) // 401 Unauthorized
    {
        echo "ERROR: You don't have permission to use the web service in this way";
    }

Advanced exercise - implementing PUT

Only do this if you are comfortable with everything we've done so far.

You'll need to put both the client script and the web service on Edward for this exercise. This is because if we are using PUT, cURL saves the PUT data to a file on the client machine before sending it and the permissions are not set up to allow this on Aquarius.

Have a go at implementing a PUT request for your web service. The web service should receive XML of the same format returned by the GET request, and update the database appropriately. Use SAX (Week 5) to parse the incoming XML.

In your web service, you'll need to use this code to read the data sent using PUT:

// Read the XML data sent using the PUT request
// into the variable $putData using this line...
$putData= file_get_contents('php://input');

// Now parse the XML (see SAX, week 5) and update the database...