Minggu, 10 April 2016

Sedikit Contoh Single Web Application

SPA itu Single Page Application, berbeda dari web tradisional yang terdiri multi-halaman, tapi apa itu sebenarnya definisi halaman? Cobalah akses situs www.ums.ac.idkawalpemilu.orgwww.facebook.comwww.gmail.com danwww.foursquare.com, jika dimonitor dari network tool yang berada di Mozilla Firefox (shortcut untuk akses: CTRL+SHIFT+Q), pertama kali mengakses www.ums.ac.id maka dibaris pertama pada kolom Method akan muncul GET dan kolom file akan muncul karakter forward slash yaitu '/' yang berarti halaman index, setelah itu cobalah mengakses link menu akademik, maka di baris pertama pada kolom file akan berganti menjadi akademik.html, yang berarti halaman index berganti menjadi halaman akademik.

Singe-Page Application
Sekarang coba mengakses www.facebook.com, lalu berganti dari Home/Beranda menuju profile, maka di kolom file akan tetap '/' yang menandakan masih tetap berada di halaman index, coba masuk ke inbox, maka baris pertama akan tetap berada di index '/', lalu coba mengakses www.gmail.com, jika berganti menu dari tab Utama, menjadi sosial, atau promosi, maka di baris pertama kolom file akan tetap '/', bila mengakses pesan terkirim maka baris pertama akan tetap '/' atau halaman index, coba lakukan pencarian di www.foursquare.com, misalnya kartasura, dan coba klik menu-menu di hasil pencarian maka dibaris pertama akan tetap berada di halaman index '/'. Demikianlah karakteristik Single-Page Application yang paling kentara, baris pertama di Network Tools tetap menunjukkan kita masih berada di Index.html.

Asynchronous HTTP Request
Lalu bagaimana bisa, konten dapat berganti-ganti namun baris pertama di Network Tools tetap menunjukkan bahwa kita berada di halaman Index? ada beragam cara untuk melakukannya, dengan menggunakan objek javascript yaitu XmlHttpRequest() secara langsung, atau lewat fungsi jQuery.ajax() atau jQuery.getJSON() untuk mengakses konten yang berada di Web Server, fungsinya jQuery.getJSON bisa dibilang mirip dengan mysql_query namun fungsi tersebut diekskusi dari browser, lalu data-data dari server tersebut kita gabungkan dengan tag-tag Html, setelah itu perbarui bagian yang perlu diperbarui menggunakan fungsi jQuery('#ID_Elemen').html().

Kelebihan SPA
1. Hemat bandwidth, karena file CSS & Javascript hanya didapatkan sekali saja dari Web Server.
2. Response lebih cepat, karena server tidak mengirim ulang file css dan javascript setiap kali pengguna melakukan interaksi.

Deep Linking (Routing)
Jika kita perhatikan, setiap kali user melakukan sebuah aksi, URL pada address bar dari situs yang sudah menerapkan Singe-Page Appication  juga ikut berganti, tombol Back dari browser juga ikut berganti, Hal itulah yang disebut dengan Deep Linking atau Routing. Kenapa perlu Deep Linking? jika hanya mendapatkan konten dengan AJAX, lalu langsung memuat data tersebut ke bagian yang akan diganti HTMLnya, maka hal itu akan membuat tombol back mati, dan URL di address bar tetap akan sama meski kontennya berubah. Hal yang demikian dapat membingungkan pengguna browser, dan kita sebagai pembuat aplikasi untuk browser tidak bisa menghilangkan tombol back tersebut. Maka, sistemlah yang harus menyesuaikan manusia pengguna akhir.

Dampak di server
Untuk aplikasi web yang menempatkan tanggung jawab penggabungan antara Data dengan tag-tag HTML berada di client, programmer hanya perlu menyediakan satu alamat URL untuk tiap entitas/tabel, lalu bagaimana cara membedakan 4 operasi CRUD jika hanya 1 URL? Dengan membedakan metode HTTP yang digunakan untuk mengakses URL tersebut, operasi Select direpresentasikan dengan metode HTTP GET, operasi Update direpresentasikan dengan operasi  PUT, operasi INSERT direpresentasikan dengan metode POST, dan operasi delete dengan metode HTTP DELETE:

Berikut contoh implementasi RESTful Web Service menggunakan bahasa pemrograman PHP:

Struktur direktori projek
xampp/
  └── htdocs/
        └── api/
             ├──controllers/
             │       └──UsersController.php
             ├──pustaka/
             │       └──Permintaan.php
             ├──index.php
             ├──.htaccess
             └──models/

HTACCESS
Untuk mendukung "pretty URLs" yang kita lihat di RESTful Web API (sesungguhnya REST lebih rumit dari yang saya jelaskan disini, paling tidak perlu teks sepanjang 3 Jam seperti disertasi penemu REST Roy Fielding, saya hanya mengambil langkah pragmatis saja mungkin wikipedia punya penjelasan bagus), kita akan menambahkan file .htaccess yang akan mengarahkan semua request ke index.php, yang perlu diingat hal ini bukanlah redirect, karena parameternya tidaklah hilang, hanya forward biasa. file .htaccess maka dari itu akan menjadi seperti berikut:

?
1
2
3
4
5
6
RewriteEngine On
RewriteBase /api/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
  

file Permintaan.php
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Permintaan {
    private $nama_metode;
    private $elemen_url;
    private $parameters;
 
    public function __construct() {
        //REQUEST_METHOD memberitahu metode apa yang dipakai pengguna
        $this->nama_metode = $_SERVER['REQUEST_METHOD'];
        //PATH_INFO mendapatkan parameter path
        $this->elemen_url = explode('/', $_SERVER['PATH_INFO']);
        $parameters = [];
   
//<code>php://input</code> merupakan stream PHP. Untuk aplikasi web "normal" yang memiliki
//header Content-Type'nya: application/x-www-form-urlencoded kita biasanya
//hanya menggunakan <code>$_POST</code>, yang sudah di'parsing'kan oleh engine php
//untuk request yang memiliki Content-Type: application/json , kita harus gunakan
//file_get_contents yang akan menghasilkan string, dan perlu di JSON_DECODE
//untuk merubahkan ke array
  
        $body_params = json_decode(file_get_contents("php://input"));
        if($body_params) {
           foreach($body_params as $nama_parameter => $nilai_parameter) {
               $parameters[$nama_parameter] = $nilai_parameter;
           }
        }
  $this->parameters = $parameters;
        return true;
    }
 public function getNamaController(){
  return ucfirst($this->elemen_url[1]);
 }
 public function getNamaMetode(){
  return strtolower($this->nama_metode).ucfirst($this->elemen_url[1]);
 }
 public function getParameters(){
  return $this->parameters;
 }
  
 public function getElemenURL(){
  return $this->elemen_url;
 }
}
file index.php
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
spl_autoload_register('memuatOtomatis');
function memuatOtomatis($namaKelas) {
    if (preg_match('/[a-zA-Z]+Controller$/', $namaKelas)) {
        include __DIR__ . '/controllers/' . $namaKelas . '.php';
        return true;
    } elseif (preg_match('/[a-zA-Z]+Model$/', $namaKelas)) {
        include __DIR__ . '/models/' . $namaKelas . '.php';
        return true;
    } else {
        include __DIR__ . '/pustaka/' . str_replace('_', DIRECTORY_SEPARATOR, $namaKelas) . '.php';
        return true;
    }
    return false;
}
 
$permintaan = new Permintaan();
 
$nama_controller = $permintaan->getNamaController().'Controller';
if(class_exists($nama_controller)) {
    $controller = new $nama_controller();
    $nama_metode = $permintaan->getNamaMetode();
    $hasilQuery = $controller->$nama_metode($permintaan);
  
 header('Content-Type: application/json; charset=utf8');
    echo json_encode($hasilQuery);
}
file UsersController.php
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class UsersController{
    public function getUsers($permintaan) {
        if(isset($permintaan->getElemenURL()[2])) {
            $user_id = (int) $permintaan->getElemenURL()[2];
            if(isset($permintaan->getElemenURL()[3])) {
                $data["pesan"] = "pengguna " . $user_id . " punya banyak ".$permintaan->getElemenURL()[3];
            } else {
                $data["pesan"] = "berikut info untuk pengguna " . $user_id;
            }
        } else {
            $data["pesan"] = "kamu ingin daftar pengguna";
        }
        return $data;
    }
 
    public function postUsers($permintaan) {
        $data = $permintaan->getParameters();
        $data['pesan'] = "data baru telah berhasil di insert";
        return $data;
    }
 
 public function patchUsers($permintaan) {
        $data = $permintaan->getParameters();
        $data['pesan'] = "data lama berhasil di update";
        return $data;
    }
 
 public function deleteUsers($permintaan) {
        $data = $permintaan->getParameters();
        $data['pesan'] = "data telah berhasil di delete";
        return $data;
    }
}
Pengaksesan PHP Restful Web Service dari javascript
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//kode untuk mendapatkan detil pengguna tertentu
$.getJSON('/api/users/' + $('#uid').val(), function(data) {
         $("#nama").html(data.nama_depan);
});
 
//kode untuk menyimpan pengguna baru
$.post('/api/users/', $('#tambahan').serialize(), function(data) {});
 
//kode untuk melakukan update data
$.ajax({
    type: 'PATCH',
    url: '/api/users/' + $('#uid').val(),
    data: $('#perubahan').serialize(),
    success: function(data) {}
});
berikut source contoh AngularJS