[Silex Framework] Make REST Web Service (2)

Melanjutkan postingan sebelumnya pada tautan https://sabitlabscode.wordpress.com/2016/05/07/silex-framework-make-rest-web-service-1/, kali ini saya akan memaparkan bagaimana membuat API untuk POST, PUT dan DELETE method (pada postingan sebelumnya telah dibahas API untuk GET method).

Apa sih beda antara GET, POST, PUT dan DELETE method ?

Penjelasan lengkapnya ada di https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html. Kalo males baca disana, singkatnya GET digunakan untuk operasi yang tidak merubah database/sistem, biasanya cuma nampilin data(view data detail, melihat list data, search, dll). Kalo POST digunakan untuk operasi yang merubah data (misal insert data baru ke dalam database server). Sedangkan PUT mirip dengan POST, tetapi PUT biasanya menyimpan informasi spesifik dari suatu data (misal kita ingin membuat operasi update data, kita biasanya punya info “id” data yang akan di update). Sedangkan DELETE dari namanya udah kelihatan biasa digunakan untuk operasi melakukan delete data, pada umumnya dia merubah data tetapi tidak melempar parameter ke dalam fungsi seperti POST dan PUT.

Sebelum melanjutkan project ini, siapa tahu nanti ada yang ga sukses mengikuti tutorial disni, anda dapat download code akhir dari project ini pada tautan berikut  https://github.com/sabithuraira/tutor_silex.  Sebelum lanjut perlu saya beritahukan bahwa nama tabel yang sebelumnya “menu_makanan” saya rubah menjadi “food_list”. Kemudian nama field pada tabel yang sebelumnya “nama” dan “harga”, saya rubah menjadi “name” dan “price”. Kok di rubah? biar orang yg ga ngerti bahasa Indonesia juga ngerti baca code dari github tadi.

Okey, sekarang mari kita lanjutkan…

Kita akan membuat sebuah perintah untuk insert data baru, masukkan code berikut :

//kita menggunakan POST
$app->post('/insert', function (Silex\Application $app, Request $request) {
    //mendefinisikan data "food_list" yang akan ditambahkan
    $data=array(
      'name' => $request->get('name'), 
      'price' => $request->get('price'),
    );

    //perintah insert data baru ke dalam tabel "food_list" dengan data yang
    //sudah dideklarasikan
    $app['db']->insert('food_list', $data);

     return $app->json("Success save data");
});

Pada code di atas terdapat petikan code “$request->get(‘name’)” maksud dari kode tersebut adalah bahwa fungsi akan mengambil sebuah nilai yang dilempar oleh client service dengan nama “name”. Misal kalo suatu saat anda membuat sebuah aplikasi android untuk insert data melalui API ini, maka aplikasi android anda harus melempar nilai bernama “name” dan “price”. Server akan menangkap kedua nilai tersebut untuk diolah kemudian.

Setelah proses insert data, sekarang kita akan membuat proses update data. Masukkan kode berikut :

$app->put('/update/{id}', function (Silex\Application $app, Request $request,$id) {
    //definisi data, sama dengan pada proses insert
    //nilai-nilai dari data diambil dari variabel yg dikirimkan oleh 
    //aplikasi client (dari aplikasi android pada penjelasan di atas)
    $data=array(
      'name' => $request->get('name'),
      'price' => $request->get('price'),
    );

     //perintah untuk melakukan update data pada tabel food_list,
     //dengan data yg sudah di masukkan dan yg di update data dengan id tertentu
     $app['db']->update('food_list', $data,array('id'=>$id));
     return $app->json("Success update data");
});

Code di atas adalah kode untuk melakukan update data melalui API, sebenarnya mirip dengan proses insert hanya saja kali ini kita memiliki informasi id dari data yang ingin diupdate.

Kemudian untuk proses delete data, masukkan kode berikut :

$app->delete(‘/delete/{id}’, function (Silex\Application $app, Request $request,$id) {
//perintah untuk menghapus data pada tabel “food_list” dengan id tertentu

$app[‘db’]->delete(‘food_list’, array(‘id’=>$id));
return $app->json(“Success delete data”);
});

Kode di atas lebih simpel karena hanya melempar suatu id kemudian menghapus data dengan id tersebut.

Dengan membuat fungsi untuk menghapus, maka kita sudah membuat contoh penerapan perintah dasar pada Rest API yaitu GET, POST, PUT dan DELETE. Kita juga sudah melihat contoh sederhana untuk melakukan operasi CRUD pada sebuah tabel. Sekarang masalahnya mungkin temen-temen merasa tidak bisa melakukan testing langsung output dari aplikasi yang kita buat. Ya, untuk dapat melihat secara langsung output dari aplikasi yang telah kita buat kita harus membuat langsung aplikasi client untuk mengkonsumsi REST API yang kita buat. Anda bisa membuat dengan aplikasi apapun, desktop app, mobile app, web app.. anda juga bebas menggunakan bahasa pemrograman apapun mau pake PHP, Java, C#, dll..

Gimana cara buat aplikasi client nya? Memang anda harus belajar lebih lanjut untuk memahami bagaimana cara membuat aplikasi clientnya. Pada postingan selanjutnya saya akan memaparkan tutorial membuat aplikasi client berbasis Android dengan Xamarin untuk mengkonsumsi REST API yang sudah kita buat pada postingan ini..

Selamat mencoba, happy coding 😀

 

Advertisements

[Silex Framework] Make REST Web Service (1)

Okey, setelah kurang lebih 5 bulan nggak posting di blog ini, akhirnya dikasih waktu dan kesempatan kembali untuk membuat catatan disini. Kali ini saya akan menjabarkan cara membuat REST Web Service dengan menggunakan Silex Framework, kalo ada yang belum tahu tentang silex framework bisa dilihat di http://silex.sensiolabs.org/. Bisa dilihat pada webnya silex adalah “The PHP micro framework based on Symfony2 Components”, jadi komponen yang digunakan oleh Silex adalah dari Symfony2 yang dari kematangan sudah teruji dalam development aplikasi website. Terus kalo ga ngerti Symfony2 gimana? buat yang ga familiar dengan symfony2 tetap bisa pake kok (saya juga ga familiar dgn Symfony2).

Kenapa pake Silex? kenapa ga pake framework lain macam Yii, Laravel atau Symfony2 sekalian?. Saya ingin membuat sebuah sistem terpisah yang bertugas cuma untuk menangani web service saya. Jika menggunakan framework seperti Yii, Laravel atau symfony2 saya rasa terlalu kompleks dan ditakutkan mempengaruhi performance dari web service yang saya bangun. Pada tutorial selanjutnya mungkin saya akan posting cara mengkonsumsi web service yang kita buat dengan Android atau Xamarin.

Laravel juga punya micro framework yang namanya Lumen, kenapa ga pake itu? Hmm, keputusan pribadi sih. Setelah googling sana-sini, walau banyak perbedaan pendapat antar developer mana yang lebih baik, saya menetapkan dan lebih tertarik explore si Silex.

Pada tutorial ini saya ingin membuat sebuah API Web Service yang dapat mengeluarkan dan mengelola data daftar makanan+harganya. Pertama-tama mari buat sebuah database dan buatlah sebuah tabel berikut :

CREATE TABLE `menu_makanan` (
 `id` INT NOT NULL AUTO_INCREMENT ,
 `nama` VARCHAR(255) NULL ,
 `harga` DECIMAL(12,0) NULL ,
 PRIMARY KEY (`id`) );

Setelah itu inputlah beberapa contoh data, misal seperti gambar berikut :

Capture

Setelah selesai dengan database, sekarang donlot Silex Framework di http://silex.sensiolabs.org/download. Yang di download lebih baik yang “slim”. Ektrak file tersebut dan masukkan ke dalam web server anda (folder letak localhost anda). Rubah nama folder “silex” anda dengan nama project yang anda inginkan (saya memberi nama project dengan “tutor_silex”). Jangan lupa install composer, download di https://getcomposer.org/. Ini dapat digunakan untuk memudahkan anda mengupdate komponen2 pada aplikasi anda secara online melalui command composer.

Buka aplikasi hello world anda pada tautan berikut : http://localhost/tutor_silex/web/index.php/hello. Akan terlihat tampilan browser dengan tulisan “Hello!”.

Sekarang pada project anda silahkan buka file pada “web/index.php”. Berikut penjelasan kode pada file tersebut :

<?php
//kode ini mendefinisikan file pada vendor/autoload.php, 
//file ini adalah sumber induk untuk mengkonsumsi components pada silex/symfony2 component.
require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

//router "hello", mendefinisikan sebuah router yang dapat dipanggil browser
//pada contoh sebelumnya kita telah memanggil tautan yang menampilkan tulisan "Hello!"
//disinilah kode yang mengeksekusi hal tersebut.
$app->get('/hello', function () {
 return 'Hello!';
});

$app->run();

Kita akan menghubungkan aplikasi kita dengan database yang telah kita buat. Untuk mengubungkan aplikasi dengan database kita akan menggunakan doctrine dalam hal ini kita harus melakukan setting pada file “composer.json” yang ada pada aplikasi dan masukkan kode berikut :

{
  "require": {
     "silex/silex": "~1.1",
     "doctrine/dbal":"~2.2",
     "phpunit/phpunit": "4.5.*"
  }
}

Pada code di atas kita mendefinisikan doctrine dan phpunit agar dapat menghubungkan aplikasi dengan database. Doctrine dan phpunit saat ini belum ada pada aplikasi anda, untuk itu kita harus mengupdate komponen anda dengan menggunakan composer. Buka command prompt anda, cd (change direktori) ke direktori project anda. Kemudian update komponen anda dengan mengetikkan perintah “composer update” pada cmd anda. Tunggu hingga proses selesai.

Setelah selesai masukkan kode berikut pada web/index.php anda :

<?php
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

//mendefinisikan koneksi ke database
$app->register(new Silex\Provider\DoctrineServiceProvider(), array(
   'db.options' => array(
      'driver' => 'pdo_mysql',
      'host' => 'localhost',
      'dbname' => 'test',
      'user' => 'root',
      'password' => '',
    ),
));

$app->get('/hello', function () {
 return 'Hello!';
});

//route untuk menampilkan daftar semua makanan pada database
$app->get('/daftar', function (Silex\Application $app,Request $request)
{
   $result=array();
   //query database
   $sql = "SELECT * FROM menu_makanan";
   $stmt=$app['db']->query($sql);
   while($row=$stmt->fetch()){
       //format data yang akan ditampilkan
       $result[]=array(
          'id' =>$row['id'],
          'nama' =>$row['nama'],
          'harga' =>$row['harga'],
       );
    }
 
    return $app->json($result);
});

//route untuk menampilkan data makanan dengan id tertentu pada database
$app->get('/daftar/{id}', function (Silex\Application $app,Request $request,$id)
{
   $result=array();
   $sql = "SELECT * FROM menu_makanan WHERE id={$id}";

   $stmt=$app['db']->query($sql);
   while($row=$stmt->fetch()){
       $result[]=array(
           'id' =>$row['id'],
           'nama' =>$row['nama'],
           'harga' =>$row['harga'],
        );
    }
 
    return $app->json($result);
});

$app->run();

Buka browser anda, kemudian buka tautan “http://localhost/tutor_silex/web/index.php/daftar&#8221;, akan tampil data dalam format json seperti berikut :

[{"id":"1","nama":"Pempek Kapal Selam","harga":"10000"},
{"id":"2","nama":"Gado-gado","harga":"10000"},
{"id":"3","nama":"Nasi Uduk","harga":"7000"}]

Kemudian buka tautan “http://localhost/tutor_silex/web/index.php/daftar/2&#8221; (kita memberikan id spesifik dari data yang ingin ditampilkan) akan muncul data dengan format seperti berikut :

[{"id":"2","nama":"Gado-gado","harga":"10000"}]

Anda dapat mengkonsumsi API tersebut. Bisa menggunakan berbagai jenis platfom seperti android, PHP, Iphone, Windows Phone, dll..

Terus kalo mau buat operasi insert/update data sama delete, gimana caranya pake REST Web Service? Hmm, berhubung lagi capek ngetik, maka postingan untuk insert/update dan delete akan saya lanjutkan pada postingan selanjutnya.. terima kasih..

Happy coding 😀

[Yii Framework] Make a Client Rest Application (GET)

Pada website yii framework telah ada sebuah wiki yang membahasa cara membuat rest service dengan Yii Framework. Pada wiki itu juga di sertakan aplikasi contoh yang telah menerapkan rest service pada aplikasinya dan dapat kita download langsung pada link yang ada pada wiki tersebut. Hanya saja walaupun telah ada aplikasi contoh yang menerapkan rest service, banyak orang mengalami kesulitan untuk membuat aplikasi client yang mengakses rest service nya dengan Yii Framework. Maka dari itu kali ini saya akan memaparkan cara untuk membuat client rest service pada Yii Framework. Tapi perlu diketahui posting kali ini hanya membahas pengaksesan data pada “GET” saja (biar ga kepanjangan).. Berikut step-step nya :

Sebelum lebih jauh, saya asumsikan anda sudah paham apa itu rest service karena saya tidak akan menjelaskan lagi tentang rest.

1. Agar seragam silahkan terlebih dahulu  mendownload aplikasi yang telah ada pada tutor Yii Fraemework di http://www.yiiframework.com/wiki/175/how-to-create-a-rest-api/. Jika sudah di download letakkan pada server local anda dan pastika aplikasi nya bisa dijalankan.

2. Craete new application in Yii Framework

3. Buatlah sebuah fungsi untuk mengakses rest service :

// terdapat 3 buah parameter, data sebagai parameter data, url untuk mengetahui akan mengakses url mana service nya, method untuk mengetahui apa metode yang digunkana (post, get, put)
public $password="password service nya";
public $usernama="username service nya";
public function submit_cURL ($data,$url,$method) 
 {
   $data[]="X_ASCCPE_PASSWORD : $this->password"; // data untuk autentikasi password
   $data[]="X_ASCCPE_USERNAME : $this->username"; // data untuk autentikasi username
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $url);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_TIMEOUT, 1000);
   if($method=='POST')
      curl_setopt($ch, CURLOPT_POST, 1);
   else if($method=='PUT')
      curl_setopt($ch, CURLOPT_PUT, 1);
   curl_setopt($ch, CURLOPT_HTTPHEADER, $data);
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
   curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
   $result = curl_exec($ch);
   curl_close ($ch);

   return $result;
 }

4. Code sebelumnya adalah fungsi untuk memanggil rest service, untuk menampilkan rest service nya buatlah pada suatu action. Service  pertama yang akan kita akan panggil rest service nya adalah action list dimana akan menampilkan semua data pada service. Pada aplikasi yang telah kita donlod sebelumnya kita bisa melihat di dalamnya terdapat sebuah folder “Rest Client Request”. Kita dapat melihat request pada “list” adalah seperti berikut :

{"requestUrl":"http://localhost/~diggindata/yii-blog-rest/index.php/api/posts","requestMethod":"GET","requestBody":"","headers":["X_ASCCPE_PASSWORD","demo","X_ASCCPE_USERNAME","demo"]}

Agar dapat mengakses nya, buatlah action seperti berikut pada controller anda :

public function actionList()
 {
   $data[]='';
   $result=$this->submit_cURL($data,"http://localhost/yii-blog-rest/index.php/api/posts","GET"); // memanggil fungsi yang menampilkan rest service dengan memasukkan beberapa parameter
   print_r($result);
 }

Jika sudah silahkan jalankan maka akan menghasilkan hasil berupa data-data seperti berikut :

[{"id":"1","title":"Welcome!","content":"This blog system is developed using Yii. It is meant to demonstrate how to use Yii to build a complete real-world application. Complete source code may be found in the Yii releases.\n\nFeel free to try this system by writing new posts and leaving comments.","tags":"yii, blog","status":"2","create_time":"1230952187","update_time":"1230952187","author_id":"1"},{"id":"2","title":"A Test Post","content":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.","tags":"test","status":"2","create_time":"1230952187","update_time":"1230952187","author_id":"1"},{"id":"10","title":"XXX","content":"YYY","tags":"","status":"1","create_time":"1302873156","update_time":"1302873156","author_id":"1"},{"id":"12","title":"XXX","content":"YYY","tags":"","status":"1","create_time":"1302873243","update_time":"1302873243","author_id":"1"},{"id":"13","title":"XXX","content":"YYY","tags":"","status":"1","create_time":"1302873251","update_time":"1302873251","author_id":"1"},{"id":"14","title":"XXX 222","content":"Bla","tags":"","status":"1","create_time":"1302894646","update_time":"1302894646","author_id":"1"}]

Setelah itu kita juga akan coba mengakses view, dimana bisa kita lihat request dari view adalah seperti berikut :

{"requestUrl":"http://localhost/~diggindata/yii-blog-rest/index.php/api/posts/1","requestMethod":"GET","requestBody":"","headers":["X_ASCCPE_PASSWORD","demo","X_ASCCPE_USERNAME","demo"]}

Anda bisa lihat beda nya pada view memiliki parameter id yang ingin di view. Agar dapat menampilkannya, silahkan buat sebuah action kembali dengan code seperti berikut :

public function actionView($id)
 {
   $data[]='';
   $result=Yii::app()->srest->submit_cURL($data,"http://localhost/yii-blog-rest/index.php/api/posts/$id","GET");
   print_r($result);
 }

Kemudian cobalah akses action tersebut, maka akan tampil data seperti berikut (misal untuk id=2):

{"id":"2","title":"A Test Post","content":"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.","tags":"test","status":"2","create_time":"1230952187","update_time":"1230952187","author_id":"1"}

Selesai… Selamat mencoba..
semoga membantu…

[Yii Framework] Use Javascript LinkedIn Api

We have know that linkedin allow developer for access their data with their API service. In this step, i will make a case about “how to create search people with linkedin api”. This is screenshoot my aplication linkedin search.

This is some step we must do for use javascript linkedin api for our website in Yii Framework.

1. Create an application in linkedin web : https://www.linkedin.com/secure/developer. You must complete your data application and then you will get API key and secret key.

2. Create an action in your controller and then make a code :

public function actionLinkedin($username=NULL,$page=0)
{

   if(isset($_POST['username']))
   {  
      if(isset($_POST['page']))
      {
         if(is_numeric($_POST['page']))
             $this->redirect(array('linkedin','username'=>$_POST['username'],'page'=>((int)$_POST['page']-1)));
         else
             $this->redirect(array('linkedin','username'=>$_POST['username'])); 
      }
      else
      {
           $this->redirect(array('linkedin','username'=>$_POST['username']));
      }
   }

    $this->render('linkedin');
 }

3. In your view, make code for your form view :

<h1>LinkedIn Search</h1>
<div id="wrapper">
  <div id="searchbar">
  <?php $form=$this->beginWidget('CActiveForm', array(
     'id'=>'searchform',
     'method'=>'POST'
  )); ?>
      <fieldset class="text ui-widget-content ui-corner-all">
          <label for="name">Keywords : </label>
          <input type="text" name="username" id="username" class="text ui-widget-content ui-corner-all" />

          <label for="name">Page : </label>
          <?php echo CHtml::dropDownList('page','',array(),array('empty'=>'-- Select --')); ?>

          <input type="submit" value="Search">
      </fieldset>

      <div id="buttons"></div>
   <?php $this->endWidget(); ?>
   </div>
   <script type="IN/Login" data-onAuth="loadData"></script>
   <div id="connections"></div>
</div>

4. Call linkedin js with your key :

<script type="text/javascript" src="http://platform.linkedin.com/in.js">
 api_key: your_api_key 
 authorize: true
</script>

5. Create a code in your view, for do some operation for your search linkedin..

<script type="text/javascript"> 

 function loadData()  // function for load search data
 {
   var searchName;
   var halaman;
   locations = [];
   if (window.location.toString().split("&").length > 1) // if in URL have parameter, then use that parameter for keyword search
   {
      searchName = window.location.toString().split("&")[1].split("=")[1].replace("+"," ");
   }
   else 
   {
      searchName = "default_keyword";  // if in URL have not parameter, user this default keyword for search
   }

   if (window.location.toString().split("&").length > 2) // if in URL have a "page" parameter, then user that parameter for page search
   {
      halaman = window.location.toString().split("&")[2].split("=")[1].replace("+"," ");
   }
   else 
   {
      halaman=0; // if in parameter have not parameter page, then default page is "0"
   }

   $("#username").val(searchName) // set username value

   // some url for call API search in linkedin, you must read linkedin api documentation for know about this
   url = "/people-search:" +
     "(people:(id,firstName,lastName,pictureUrl,industry,publicProfileUrl,headline,location,positions))" +
     "?start="+(halaman*20)+"&count=20&keywords=" + searchName 

   // some function from linkedin for do search
   IN.API.Raw(url)
     .result(function(result) {
        $.ajax({
        url: "<?php echo Yii::app()->createUrl('ControllerName/ActionName')?>", // we want to know how many page we get from result searh for use in choice of page. In this case we will use ajax and call our action
        data: "haha=" + result.people._total,  // parameter that sent total people from search result
        success: function(data){  // if success
            $("#page").html(data);  // we set to control page
        }
     });

     // we set some html code for view our result
     halnow=parseInt(halaman)+1;
     profHTML ="Search Result Keyword \""+searchName+"\" page "+halnow;
     profHTML += "<table class=\"maaron\" width=\"100%\"><tr><th>Profile Picture</th><th>Name</th><th>Title at Company</th><th>Company</th><th>Public Profile URL</th><th>View</th></tr>";
     for (var index in result.people.values)
     {
        profile = result.people.values[index] 
        id = profile.id + ":" + profile.firstName + " " + profile.lastName 
        if (profile.pictureUrl)
        {
            profHTML += "<tr><td><img id=\"" + id + "\" border height=30 align=\"left\" src=\"" + profile.pictureUrl + "\"></td>";
        }
        else
        {
            profHTML += "<tr><td><img id=\"" + id + "\" border height=30 align=\"left\" src=\"http://static02.linkedin.com/scds/common/u/img/icon/icon_no_photo_60x60.png\"></td>"; 
        }
        profHTML += "<td>"+profile.firstName + " " + profile.lastName + "</td>";
        profHTML += "<td>"+profile.headline + "</td>";
        profHTML += "<td>"+ profile.industry + "</td>";
        profHTML += "<td><a href="+ profile.publicProfileUrl +" target='_blank'>Public Link</a></td>";
        profHTML += "<td><a href='?r=search/linkview&id="+profile.id+"'>View</a></td></tr>";
    }
    profHTML+="</table>";
    $("#connections").html(profHTML);
   });
 }

 $("#searchbar").keypress(function(e) // event when user input some keyboard
 {
    if (e.keyCode == 13) { // when user input "enter"
       e.preventDefault();
       if ($("#username").val() != "") 
       {
         loadData();
         return false;
       }
    }
  });
</script>

6. Because we have some action that call AJAX for set the page choice, then we must create that action. So in your controller, create an action like this :

public function actionTarik()
 {
   $haha = $_GET["haha"];
   $totalhalaman=$haha/20+1;
   echo "<option>-- Select --</option>";
   for($i=1;$i<=$totalhalaman;++$i)
   {
       echo '<option value='.$i.'>'.$i.'</option>';
   }
 }

Finsihed.. Hope help you.. 😀
Sorry for my bad English..

Yii Framework REST Web Service and Windows Phone 7 sebagai Client (POST Insert Data)

Setelah kemarin kita telah mengupas cara view data suatu aplikasi lewat aplikasi client lain, sekarang saya akan mencoba memaparkan cara input data menggunakan REST dengan aplikasi client yang tentu dalam hal ini saya contohkan dengan menggunakan windows phone 7. Project yang akan kita buat adalah meneruskan project sebelumnya dari postingan ini. Jadi fungsi-fungsi yang telah ada disana tidak akan saya tulis ulang pada postingan ini.

Pertama-tama pada aplikasi yii anda tetap di controller yang sama seperti postingan sebelumnya, buatlah sebuah action yang digunakan untuk menginput nilai lewat REST API.

// digunakan untuk proses input ke database
 public function actionCreate()
 {
   switch($_GET['model'])
   {
       case 'kab': // apabila yang di request adalah "kab", maka akan menginput data pada tabel kabupaten
         $model = new MKab; 
         break;
      default:
         $this->_sendResponse(501,sprintf('Mode <b>create</b> is not implemented for model <b>%s</b>',$_GET['model']) );
        // jika yang di request tidak ada, maka akan error
        Yii::app()->end();
   }
   foreach($_POST as $var=>$value) { // mengecek attribute satu per satu sesuai dengan inputan user
     if($model->hasAttribute($var))
        $model->$var = $value;
     else // jika ada inputan user yang salah, maka akan di tampilkan pesan error
        $this->_sendResponse(500, sprintf('Parameter <b>%s</b> is not allowed for model <b>%s</b>', $var,$_GET['model']) );
   }
   if($model->save()) // jika data berhasil disimpan, maka akan di tampilkan pesan berupa data hasil yang telah disimpan tadi
      $this->_sendResponse(200, CJSON::encode($model)); // mengirim pesan
   else { // jika data tidak berhasil disimpan, maka akan menampilkan pesan error
      $msg = "<h1>Error</h1>";
      $msg .= sprintf("Couldn't create model <b>%s</b>", $_GET['model']);
      $msg .= "<ul>";
      foreach($model->errors as $attribute=>$attr_errors) {
          $msg .= "<li>Attribute: $attribute</li>";
          $msg .= "<ul>";
          foreach($attr_errors as $attr_error)
              $msg .= "<li>$attr_error</li>";
          $msg .= "</ul>";
      }
      $msg .= "</ul>";
      $this->_sendResponse(500, $msg );
    }
 }

Penjelasan dari kode tersebut sudah saya selipkan di baris-baris code di atas.

Nah, setelah selesai membuat action untuk input data, sekarang kita akan membuat sebuah aplikasi client yang digunakan untuk menginput datanya. Bukalah visual studio anda lalu buatlah project windows phone baru. Kemudian buatlah form seperti berikut :

Kita memiliki 3 buah inputan disana yaitu inputan untuk kode daerah, nama daerah dan kode provinsi tersebut. Inputan tersebut sendiri sudah kita sesuaikan dengan model Kabupaten yang ada di dalam aplikasi yii kita. Kemudian karena inputan ini melibatkan 2 buah tabel yaitu tabel kabupaten yang akan diinput dan tabel provinsi yang mana akan berelasi dengan tabel kabupaten, maka kita perlu membuat 2 buah class baru pada aplikasi windows phone kita. Buatlah sebuah folder pada project anda dengan nama “ApiClass” dan buatlah 2 buah class baru yaitu class “Daerah” yang akan mengacu ke tabel provinsi, dan class “Kab” yang akan mengacu ke tabel kabupaten. Lalu pada class daerah masukkan code berikut :

namespace sirusa.ApiClass
{
  public class Daerah
  {
     public string kode_daerah { get; set; }
     public string nama_daerah { get; set; }
  }
}

dan class kab masukkan code berikut :

namespace sirusa
{
  public class Kab
  {
    public int kode_kab { get; set; }
    public string kode_daerah { get; set; }
    public string nama_kab { get; set; }
  }
}

Pada saat pertama kali aplikasi wp7 ini dijalankan, pada inputan provinsi kita menginputnya dengan cara memilih provinsi yang sudah ada pada aplikasi server. Untuk itu, kita harus menyediakan sebuah API untuk mengambil list nama-nama provinsi dari aplikasi server. Untuk ini kita sudah pernah membahas bagaimana cara mengambil data dengan rest pada contoh postingan sebelumnya, silahkan terapkan fungsi tersebut untuk kasus ini..

Kemudian setelah kita telah membuat API untuk mengambil semua provinsi pada server, buatlah sebuah fungsi yang dimana setiap kita membuka aplikasi maka list provinsi yang ada di server langsung muncul di aplikasi wp7 kita. Pada mainpage.xaml.cs masukkan code berikut :

private List<Daerah> daftard = new List<Daerah>();//variabel untuk menyimpan data provinsi, digunakan agar
 // tidak melakukan load berulang kali ke server karena provinsi di anggap tidak terlalu banyak isinya
 // dan tidak sering mengalami perubahan, jadi disimpan di dalam satu variabel saja lebih dahulu
 private void GetDaerah()
 {
   string url = "http://localhost/sirusanew/index.php?r=webapi/list&model=daerah";// api yang di akses
   WebClient req = new WebClient(); 
   req.DownloadStringCompleted += (s, e) =>//jika proses download data selesai
   {
      if (e.Error == null) // jika kondisi tidak error
      {
         if (!string.IsNullOrEmpty(e.Result)) // jika data tidak kosong
            daftard = JsonConvert.DeserializeObject<List<Daerah>>(e.Result); // masukkan data ke dalam variabel daftard
         foreach (Daerah aa in daftard)
         {
            listBox1.Items.Add(aa.nama_daerah); // set data daftard ke dalam listbox
         }
      }
   };
   req.DownloadStringAsync(new Uri(url));
 }

Setelah itu pada constructor buat seperti berikut :

public MainPage()
 {
   InitializeComponent();
   GetDaerah(); // memanggil fungsi getdaerah()
 }

Setelah itu maka pertama kali membuat aplikasi akan muncul list provinsi seperti berikut :

Kemudian saatnya kita membuat fungsi untuk menginput data nya. Pada mainpage.xaml.cs masukkan code berikut :

 // event yang akan di jalankan ketika melakukan klik pada tombol button
 private void button1_Click(object sender, RoutedEventArgs e)
 {
    WebClient webClient = new WebClient();
    webClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
    var uri = new Uri("http://localhost/sirusanew/index.php?r=webapi/create&model=kab", UriKind.Absolute);// url yang dituju untuk input data
    StringBuilder postData = new StringBuilder();
    postData.AppendFormat("{0}={1}", "kode_kab", HttpUtility.UrlEncode(textBox2.Text)); // data-data yang akan dismipan dimasukkan ke dalam string
    postData.AppendFormat("&{0}={1}", "nama_kab", HttpUtility.UrlEncode(textBox1.Text));
    postData.AppendFormat("&{0}={1}", "kode_daerah", HttpUtility.UrlEncode(daftard.ElementAt(listBox1.SelectedIndex).kode_daerah));
    webClient.Headers[HttpRequestHeader.ContentLength] = postData.Length.ToString();
    webClient.UploadStringCompleted += new UploadStringCompletedEventHandler(webClient_UploadStringCompleted);
    // jika upload data selesai, maka akan menjalankan event webClient_uploadStringComplete
    webClient.UploadProgressChanged += webClient_UploadProgressChanged;
    // jika upload data dalam progress maka akan menjalankan even webClient_UploadPorgressChanged
    webClient.UploadStringAsync(uri, "POST", postData.ToString()); 
 }
 // event yang dijalankan pada saat upload data selesai
 void webClient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
 {
    MessageBox.Show(e.Result);// menampilkan pesan sesuai yang diberikan dari serve
 }
// event yang dijalankan pada saat upload data dalam progress
 void webClient_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
 {
    MessageBox.Show(string.Format("Progress: {0} ", e.ProgressPercentage)); // menampilkan pesan progress
 }

Okeh, selesai.. sekarang saatnya uji coba.. jika sudah benar ketika anda save data makan data yang anda masukkan akan masuk ke server langsung..

Selamat mencoba..

Semoga membantu… 😀

Yii Framework REST Web Service and Windows Phone 7 sebagai Client

Postingan saya terdahulu pernah membahas penerapan web service pada Yii Framework dengan menggunakan SOAP disini. Pada postingan tersebut juga saya memaparkan bagaimana suatu aplikasi client mengakses web service kita yang dimana saya contohkan client dengan menggunakan PHP dan C#. Postingan kali ini juga masih menyangkut web service hanya saja yang saya gunakan bukanlah SOAP tetapi REST. Untuk penjelasan lengkap perbedaan masing-masing metode dapat anda googling aja ya.. Menurut saya sendiri perbedaan umum dari kedua metode tsb adalah SOAP mengizinkan suatu aplikasi mengakses suatu API yang merupakan sebuah fungsi dari server yang menyediakan service, sementara REST lebih kepada mengakses URL dari suatu aplikasi yang menyediakan service.

Artikel yang cukup lengkap tentang penerapan REST pada Yii Framework bisa anda lihat disini (saya juga coba-coba dan nyontek dari sana). Sedangkan postingan kali ini saya hanya terapkan cara mengambil data (mungkin akan ada kelanjutannya pada postingan selanjutnya) dari suatu aplikasi server dengan menggunakan aplikasi lain yang kita sebut sebagai aplikasi client. Pertama misalnya saya ingin mengizinkan aplikasi lain dapat mengakses data master kabupaten dari aplikasi saya dengan menggunakan rest web service. Pertama buatlah sebuah controller baru misal saya beri nama webapiController. Kemudian buatlah sebuah action yang digunakan untuk mengambil data dari suatu model :

// action yang akan di panggil dari apliakasi lain
 public function actionList()
 {
   switch($_GET['model'])
   {
      case 'kab': // jika user request data "kab" maka akan di tampilkan data pada master kabupaten
        $models = Kabupaten::model()->findAll(array('select'=>array('nama_kab','kode_kab')));
        break;
     default: // jika yang di request user tidak ada, maka akan mengirimkan pesan error
        $this->_sendResponse(501, sprintf('Error: Mode <b>list</b> is not implemented for model <b>%s</b>',$_GET['model']) );
      Yii::app()->end();
   }

   if(empty($models)) { // jika tabel yang dituju ada tetapi isi data nya kosong, akan menampilkan pesan error
      $this->_sendResponse(200, 
      sprintf('No items where found for model <b>%s</b>', $_GET['model']) );
   } else {
      $rows = array();
      foreach ($models as $model)
      {
         $rows[] = $model->attributes;// memasukkan semua attribute suatu data ke dalam array
      }
      $this->_sendResponse(200, CJSON::encode($rows));
      // jika data yang diinginakan ada, maka data tersebut akan di convert dalam
      // format json kemudian akan mengirimkan data-data tersebut
    }
 }

Anda dapat melihat penjelasan masing-masing code dari komentar-komentar yang sudah disipkan di code tersebut. Nah, pada code di atas terdapat fungsi $this->_sendResponse yang artinya pada controller ini kita pasti punya sebuah fungsi bernama “_sendResponse”. Maka buatlah sebuah fungsi tersebut :

// digunakan untuk mengirimkan respon pada suatu request
 private function _sendResponse($status = 200, $body = '', $content_type = 'text/html')
 {
    $status_header = 'HTTP/1.1 ' . $status . ' ' . $this->_getStatusCodeMessage($status);
    header($status_header);
    header('Content-type: ' . $content_type);
    if($body != '') // jika data yang ingin dikirim tidak kosong, maka tampilkan data tersebut
    {
      echo $body;
    }
    else // jika data yang ingin dikirim kosong, maka kirim pesan sesuai statusnya.
    {
       $message = ''; // variabel yang digunakan untuk membuat pesan header pada pesan
       switch($status) // mengeset pesan sesuai dengan statusnya
       {
         case 401:
            $message = 'You must be authorized to view this page.';
            break;
        case 404:
            $message = 'The requested URL ' . $_SERVER['REQUEST_URI'] . ' was not found.';
            break;
        case 500:
            $message = 'The server encountered an error processing your request.';
            break;
        case 501:
            $message = 'The requested method is not implemented.';
            break;
       }
       $signature = ($_SERVER['SERVER_SIGNATURE'] == '') ? $_SERVER['SERVER_SOFTWARE'] . ' Server at ' . $_SERVER['SERVER_NAME'] . ' Port ' . $_SERVER['SERVER_PORT'] : $_SERVER['SERVER_SIGNATURE'];
       // signature, pesan-pesan mngenai informasi server

       // pesan yang akan di tampilkan kepada user
       $body = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
          <html>
             <head>
                <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
                <title>' . $status . ' ' . $this->_getStatusCodeMessage($status) . '</title>
             </head>
             <body>
                <h1>' . $this->_getStatusCodeMessage($status) . '</h1>
                <p>' . $message . '</p>
                <hr />
                <address>' . $signature . '</address>
             </body>
          </html>';
       echo $body;
     }
    Yii::app()->end();
 }

penjelasan code tersebut juga ada pada code di atas. Nah, pada code di atas juga ada sebuah fungsi  _getStatusCodeMessage, artinya kita juga harus membuat fungsi tersebut :

// mengembalikan pesan dari suatu request
 private function _getStatusCodeMessage($status)
 {
   $codes = Array(
     200 => 'OK',
     400 => 'Bad Request',
     401 => 'Unauthorized',
     402 => 'Payment Required',
     403 => 'Forbidden',
     404 => 'Not Found',
     500 => 'Internal Server Error',
     501 => 'Not Implemented',
   );
   return (isset($codes[$status])) ? $codes[$status] : '';
 }

Setelah membuat code tersebut, anda sudah selesai membuat rest api nya, dan untuk melihat hasilnya, cobalah mengakses URL berikut di browser anda :

http://localhost/namaaplikasianda/index.php?r=namacontroller/list&model=kab.

Parameter yang perlu anda masukkan adalah nama controllernya, nama action dalam hal ini “actionList”, nama variabel $_GET yang anda kirim beserta isi variabel $_GET nya. Setelah itu akan muncul tampilan seperti berikut :

Gambar di atas adalah hasil yang akan tampil dimana yang akan di tampilkan adalah kumpulan data yang kita ambil dari proses action list tadi. Kemudian bagaimana agar data tersebut data di akses dari aplikasi lain?

Okeh, saya akan memberikan contoh cara mengakses data tersebut dengan menggunakan Windows Phone 7. Anda dapat menggunakan platform apapun untuk mengakses data ini baik dengan PHP, java, iphone, dll asalkan anda menguasainya.. tapi dalam contoh ini saya akan tunjukkan menggunakan windows phone 7 karena kebetulan saya tertarik dengan platform satu ini..

Pertama-tama buatlah sebuah aplikasi baru pada windows phone 7. Karena kita mengolah data json, kita akan memnggunakan sebuah library untuk mempermudah kita mengolahnya dalam windows phone 7. Library tersebut dapat anda download disini, dan masukkan library tersebut ke dalam aplikasi anda dan jangan lupa definisikan ke dalam aplikasi anda dengan memasukkan code berikut pada mainpage.xaml.cs :

using Newtonsoft.Json;

Buatlah sebuah class baru dengan nama Kab.cs dan masukkan ke dalamnya code berikut :

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace sirusa
{
  public class Kab
  {
     public int kode_kab { get; set; }
     public string kode_daerah { get; set; }
     public string nama_kab { get; set; }
   }
}

Setelah itu pada mainpage.xaml.cs tambahkan sebuah fungsi berikut :

private void GetData()
 {

  string url = "http://localhost/sirusanew/index.php?r=webapi/list&model=kab";
  // definisi url yang akan di akses 
  WebClient req = new WebClient();
  req.DownloadStringCompleted += (s, e) =>
  {
    if (e.Error == null)
    {
       string tt = ""; // nilai yang akan di tampilkan
       if (!string.IsNullOrEmpty(e.Result))
       {
          Kab[] deserializedJSON = JsonConvert.DeserializeObject<Kab[]>(e.Result);
          // konversi nilai json ke dalam class Kab dengan format array karena nilainya bisa lebih dari satu buah
          foreach (var k in deserializedJSON)
          {
             tt += k.nama_kab; // memasukkan nilai nama kabupaten untuk di tampilkan
          }
          MessageBox.Show(tt); // menampilkan nilai yang sudah disimpan tadi
       }
     }
   };
   req.DownloadStringAsync(new Uri(url));
 }

Setelah itu rubah contrstructornya menjadi seperti berikut :

// Constructor
 public MainPage()
 {
   InitializeComponent();
   GetData(); //memanggil fungsi getdata
 }

Jalankan aplikasi anda dan akan tampil seperti berikut :

 

 

Okeh.. selesai…

Selamat mencoba…

Semoga membantu… 😀

[Yii Framework] Membuat Web Service SOAP(3)

Sebelumnya saya sudah memaparkan step-step untuk membuat web service pada Yii Framework disini dan disini. Yah kedua postingan itu barulah memaparkan cara untuk membuat service yang mengizinkan client mengambil data. Nah, bagaimana jika ada kasus dimana kita ingin mengizinkan user melakukan perubahan data?? baik itu Insert data baru, update, maupun delete?? Okeh, mari kita bahas cara membuat itu semua dengan Yii Framework..

Pertama-tama, buatlah sebuah fungsi yang mengizinkan user melakukan manipulasi data. Saya hanya akan membuat sebuah fungsi INSERT dan UPDATE data baru dengan web Service. Kurang lebih code dari fungsi yang saya buat adalah seperti berikut:

	/**
	 * @param Satu contact model
	 * @return boolean
	 * @soap
	 */
	public function saveSatu($data)
	{
		if(($oldData=Satu::model()->findByAttributes(
                    array('satusatu'=>$data->satusatu)))!==null)
		{
			$oldData->attributes=$data->attributes;
			return $oldData->save();
		}
		else
		{
			$model=new Satu;
			$model->attributes=$data->attributes;
			return $model->save();
		}
	}

Penjelasan : Pada fungsi di atas saya membuat sebuah fungsi “saveSatu()” dengan parameter nya yang adalah sebuah object “Satu”. Di dalam fungsi itu akan secara otomatis mendeteksi apakah data yang di input sudah ada atau belum. Sehingga jika data nya sudah ada, maka program akan melaksanakan “UPDATE” data secara otomatis. Tapi jika data yang di masukkan belum ada, maka program akan melakukan “INSERT” data.

Setelah kita telah membuat sebuah fungsi yang mengizinkan user untuk melakukan “INSERT” dan “UPDATE” data, maka kita tinggal membuat sebuah client aplikasi yang mengizinkan client untuk mengizinkan fungsi tersebut.

Pada client aplikasi yang saya buat, saya telah membuat sebuah model “Satu” yang attributnya saya buat sama persis dengan model “Satu” yang ada pada server application service nya. Saya juga telah membuat form entri data yang dimana inputan-inputan pada form tersebut akan di tangkap sebagai nilai-nilai yang akan di input ke dalam service yang telah kita buat. Lalu saya membuat sebuat “actionCreate()” pada controller saya yang melakukan penyimpanan data lewat service, kurang lebih saya edit code nya menjadi seperti berikut:

public function actionCreate()
{
	$model=new Satu;
	$client=new SoapClient('http://localhost/namaProject/index.php?r=satu/quote');

	if(isset($_POST['Satu']))
	{
		$model->attributes=$_POST['Satu'];
		$client->saveSatu($model);
	}

	$this->render('create',array(
		'model'=>$model,
	));
}

Penjelasan : Fungsi di atas akan menangkap semua inputan pada form inputan yang telah kita buat. Yah, ini sama persis dengan step “INSERT” data biasa. Hanya saja, disini saya tidak menjalankan perintah untuk menyimpan data tersebut, tapi saya memerintahakan program menjalankan fungsi Service yang sudah kita buat sebelumnya. Dan setelah form tersebut dijalankan, data yang ada pada aplikasi server telah terinput datanya dengan yang sudah kita input tadi…

Selesai…. Selamat mencoba…

Semoga membantu 😀

%d bloggers like this: