Topic 7: REST

Exercise

Introduction

This exercise will allow you to develop a REST-compliant web service, and also develop a client to connect to the service.

Writing the REST web service

  1. Copy and paste this code and save it as restserver.php. 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", "dftitutorials");
    mysql_select_db ("dftitutorials");
    
    if($a<=0)
    {
        // What HTTP code should we return if $a is invalid (0 or less)?
    
        exit; // quit on error
    }
    
    // Check that the ID exists
    $result=mysql_query("select * from hits where ID=$a");
    if(mysql_num_rows($result)==0)
    {
        // What HTTP code should we return if the ID doesn't exist? 
    
        exit; // quit on error
    }
    
    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. You can do this in a similar way to your Week 1 answer. Look at your Week 1 answer to remind yourself of the column names in the hits table, or log on to the database at http://edward/phpmyadmin
  3. Add code to handle a "DELETE" request. This should be an SQL DELETE query to delete the song with the ID sent to the script.
  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 standard URL such as:
    http://edward/students/pjones/restserver.php?id=1009
    (note the use of /students/pjones rather than ~pjones. They link to the same folder. The reason why you should do this is that there are difficulties with using mod_rewrite with the ~username syntax for user directories).

    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. Also test out using a non-existent ID or an invalid ID (one of 0 or less). You'll need a Firefox extension for this, as Firefox does not report HTTP error codes to the end user by default. The extension is called Live HTTP Headers. Download it from here. You will be able to access the add-on through Tools-Live HTTP headers. This will show a window which displays the entire HTTP request and response for each communication with the server.

Using mod_rewrite to set up a REST style URL

Having set up your web service, have a go at setting up a REST style URL for it. Rather than something like

 http://edward/students/pjones/restserver.php?id=1009 
the URL should read something like:
 http://edward/students/pjones/hit/1009 

Write a .htaccess file to do this, as described in the notes, and upload it to your public_html directory on the Edward server.

Writing a client to the REST web service

Introduction: Use of call_web_service.php to simplify connecting to the service

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 long-winded. 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). You can download it here (ZIP file). 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/hit/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/hit/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:

Exercise instructions

  1. Create this form. It is a test form which allows a user to input a song ID. This obviously isn't very user-friendly to a user of the site, but you are only using it to test out the REST web service.
    <html>
    <head>
    <style type='text/css'>
    body { background-color: black; color: white }
    </style>
    </head>
    <body>
    
    <h1>Welcome to the IndieWorld Test REST client</h1>
    <p>Not very user-friendly, for test purposes only. When you write your
    assignment, make sure it's more user-friendly than this; obviously your average
    web user is not going to know what an "HTTP request" is!!!!  </p>
    <form method="post" action="rest_client.php">
    ID of song:
    <input name="id" />
    <br />
    HTTP Request Type:
    <select name="requesttype">
    <option>GET</option>
    <option>DELETE</option>
    <option>PUT</option>
    </select>
    <br />
    XML Data to Send (PUT only):<br />
    <textarea name="data"></textarea> <br />
    <input type='submit' value='Go!' />
    </form>
    </body>
    </html>
    
    
  2. Make a copy of your existing IndieWorld client script (from Topic 6, i.e. the one which parses the XML data using SAX or SimpleXML) so that it reads in the song ID from the form above, rather than the artist, and sends a GET request to your REST web service, using call_web_service.php (see above). Ensure that you put the song ID in the URL when calling the web service. Save it as rest_client.php
  3. Imagine IndieWorld have the rights to delete songs from HitTastic! Change your script so that it reads whatever method that the user selected in the form, and test out a DELETE request to the HitTastic! REST web service to delete a song with a given ID (remember that your form has a DELETE option). 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.

Have a go at implementing a PUT request for your web service. Just for the purposes of testing (obviously in the real world it would not be done this way!) add an extra field to your form, allowing the user to enter XML of the updated details of the song. The IndieWorld script should send a PUT request to the web service, and send the XML the user entered, in the same format as that returned from the GET request.

You then need to modify the web service to parse the incoming XML. Use SAX or SimpleXML (Topic 6) to parse the incoming XML and then perform an SQL UPDATE statement using the information extracted from the 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 topic 6) and update the database...