Friday, January 11, 2013

Playnig With HTTP Methods

I am highly interested in RESTful web services these days :) . So I tried to implement my own RESTful API and wrote REST client to communicate with the service. GET, POST, PUT, DELETE are basic HTTP methods used in REST services (details of HTTP methods can be found here) . Lets see how I implemented basic CRUD operations using HTTP methods.

For the sake of simplicity I have simply echoed the request body and selected request headers back as the service implementation.


Service implementation in PHP (MyService.php)

<?php 
/**
 * Sample REST controller
 * 
 */
$method = $_SERVER['REQUEST_METHOD'];
$request = explode("/", substr(@$_SERVER['PATH_INFO'], 1));

echo "Request Method : ".$method;
echo "\n";

if(strlen($request[0])>0){
    
    if(strcmp($method, "GET")==0){
        printHeaders();
        print_r($_GET);
        
    }else if(strcmp($method, "POST")==0){
        printHeaders();
        print_r($_POST);
        
    }else if(strcmp($method, "PUT")==0){
        printHeaders();
        parse_str(file_get_contents("php://input"),$post_vars);
        print_r($post_vars);
    }
    
}else{
    echo "no resources found!";
}

function printHeaders(){
        $headers = apache_request_headers();
        echo "Authorization : ".$headers['Authorization'];
        echo "\n";
        echo "MyOwnHeader : ".$headers['MyOwnHeader'];
}
?>

REST client code for invoking REST service with a POST request.

public void postRequest() throws MalformedURLException, IOException{
 URL url=new URL("http://kanishka-d/rest/MyService.php/myresource");
 HttpURLConnection httpCon=(HttpURLConnection) url.openConnection();
 httpCon.setRequestMethod("POST");
 //set request headers
 httpCon.setRequestProperty("Authorization", "Client-ID 1133");
 httpCon.setRequestProperty("MyOwnHeader", "Hello Sri Lanka!");

 httpCon.setDoOutput(true);
 
 String urlParameters = "PARAM1=" + URLEncoder.encode("Param val 1", "UTF-8")+"&";
 urlParameters+="PARAM2="+URLEncoder.encode("Param val 2", "UTF-8");
 //Send request
 DataOutputStream wr = new DataOutputStream(
   httpCon.getOutputStream());
 wr.writeBytes(urlParameters);
 wr.flush();
 wr.close();
 
 //Get service Response 
 InputStream is = httpCon.getInputStream();
 BufferedReader rd = new BufferedReader(new InputStreamReader(is));
 String line;
 StringBuilder response = new StringBuilder();
 while ((line = rd.readLine()) != null) {
  response.append(line);
  response.append('\r');
 }
 rd.close();
 wr.close();
 httpCon.disconnect();
 
 System.out.println(response.toString());
}

Output:
Request Method : POST
Authorization : Client-ID 1133
MyOwnHeader : Hello Sri Lanka!
Array
(
    [PARAM1] => Param val 1
    [PARAM2] => Param val 2
)

Making PUT request is simple as just changing request method.


httpCon.setRequestMethod("POST");


client side implementation for DELETE and GET methods is different. Because DELETE and GET doesn't expect HTTP request body.

implementing GET request is slightly different from the implementation of the POST/PUT request. Main difference is embedding data in URL itself. and no data in request body.(see below code).

public void getRequest() throws MalformedURLException, IOException{
    String url="http://kanishka-d/rest/MyService.php/myresource?";
    url+="PARAM1=" + URLEncoder.encode("Param val 1", "UTF-8")+"&";
    url+="PARAM2="+URLEncoder.encode("Param val 2", "UTF-8");
    URL urlObj=new URL(url);
    HttpURLConnection httpCon=(HttpURLConnection) urlObj.openConnection();
    httpCon.setRequestMethod("GET");
    //set request headers
    httpCon.setRequestProperty("Authorization", "Client-ID 1133");
    httpCon.setRequestProperty("MyOwnHeader", "Hello Sri Lanka!");

    httpCon.setDoOutput(false);

    //Get service Response 
    InputStream is = httpCon.getInputStream();
    BufferedReader rd = new BufferedReader(new InputStreamReader(is));
    String line;
    StringBuilder response = new StringBuilder();
    while ((line = rd.readLine()) != null) {
        response.append(line);
        response.append('\r');
    }
    rd.close();
    httpCon.disconnect();

    System.out.println(response.toString());
}
Output :
Request Method : GET
Authorization : Client-ID 1133
MyOwnHeader : Hello Sri Lanka!
Array
(
    [PARAM1] => Param val 1
    [PARAM2] => Param val 2
)

Implementation of the DELETE client request is almost same as GET.

Please note that I have used Java for the client side. I have used HttpURLConnection . We can do same with the apache http client with less lines of code.

We can implement a REST API and Client with tease building blocks easily.

References :
Web API Design (Apigee)

0 comments:

Post a Comment

© kani.stack.notez 2012 | Blogger Template by Enny Law - Ngetik Dot Com - Nulis