Topic 4: POST-based web services and clients

In this session, you will write a web service which updates the database by adding new data, namely a review for a given song.

POST data using Slim

So far we have only looked at GET requests, however to create new data we need to use POST. How do we handle POST data in Slim? Firstly, we set up a 'post' rather than a 'get' route, and then we use the request's getParsedBody() method to extract the POST data. For example, this sets up a POST route /student/create:


// Include all the Slim dependencies. Composer creates an 'autoload.php' inside
// the 'vendor' folder which will, in turn, include all required dependencies.
require 'vendor/autoload.php';


// Create a new Slim App object.
$app = new \Slim\App;

$app->post('/student/create', function ($req, $res, array $args) {
    $post = $req->getParsedBody();
    $res->getBody()->write("Student details : Name: ". $post['name']. " Username: ". $post['username']. " Course: " . $post['course']);
    return $res;
});


$app->run();

In this example, we could set up a form with an action of "/student/create" and fields with names of name, username and course, and the Slim application would read, and display, this data.

Exercise 1

This exercise will involve creating a review for a song, so we will use POST, as per the principles of REST.

Sending a POST request using cURL

So far we have seen how to connect to a web service using cURL to send a GET request, however what about a POST request?

Rather than adding the data to the end of the URL using a query string, you set the CURLOPT_POSTFIELDS option with the data you want to POST. See the example below, in which $dataToPost is an associative array describing a new flight. It is sent to the REST URL http://www.solentairways.com/flight/create:

$connection = curl_init();
curl_setopt($connection, CURLOPT_URL, "http://www.solentairways.com/flight/create");
$dataToPost = 
    ["origin" => "London" ,
     "dep" => "0900",
     "arr" => "1600",
     "destination" => "New York",
     "aircraft" => "Boeing 777",
     "flightnumber" => "SA123"];
curl_setopt($connection,CURLOPT_RETURNTRANSFER,1);
curl_setopt($connection,CURLOPT_POSTFIELDS,$dataToPost);
$response = curl_exec($connection);
curl_close($connection);
would send the specified data describing a new flight to the /flight/create route. /flight/create could then read the various fields with with $req->getParsedBody(). For example:
$app->post("/flight/create", function($req, $res, array $args) {
    $postData = $req->getParsedBody();
    // $postData["origin"] is the origin, $postData["dep"] is the departure time, etc.
});

Exercise 2

Return to your "fan" website from last time. On the "fan" website, allow the user the ability to review each song from HT-Tracks. This should be done by writing a new page on your fan site which connects to the HT-Tracks download web service, which you wrote above.


Web service clients with POST

Do this as follows:

How to test the HTTP status code from a client

In the last question of the exercise, you were asked to send back an HTTP status code to the client if the review was blank. However, we have not yet looked at how you can test for an HTTP code sent back from a remote script. Luckily, if you are using cURL it's fairly straightforward. Once you have done your cURL request you query the CURLINFO_HTTP_CODE property to obtain the HTTP code returned by the web service, for example:

$connection = curl_init();
curl_setopt($connection, CURLOPT_URL, "http://remoteserver/script.php");
curl_setopt($connection,CURLOPT_RETURNTRANSFER,1);
curl_setopt($connection,CURLOPT_HEADER,0);
$response = curl_exec($connection);

$httpCode = curl_getinfo($connection,CURLINFO_HTTP_CODE);
echo "The script returned the HTTP status code: $httpCode <br />";

curl_close($connection);

Note how the line:

curl_setopt($connection,CURLOPT_HEADER, 0);
is still present. We can get the status code without having to include the full HTTP header in the output.

Exercise 3

  1. Modify your clientreview.php to test which HTTP code is returned from the web service and display an appropriate message accordingly.

  2. Add a new route to your web service, getReviews, which returns all reviews for the song with a particular ID as JSON. Modify your fan site to have an additional reviews page, which shows all reviews for a particular song by connecting to your web service and parsing the JSON returned. Link this reviews page to your main fan page, so that each song has a "Review" link. Ensure the fan site's reviews page has the same look and feel as your main fan site page.