Halo Pembaca,

Saat ini saya sedang mengembangkan versi berikutnya dari www.kalender-indonesia.com. Sebelumnya saya menggunakan "framework" webservice yang contohnya bisa Anda lihat di artikel ini: Android, PHP, dan Database MySQL (Bagian 2). Untuk pengembangan kali ini saya menggunakan framework Jacwright RestServer. Ini ringan dan simpel, sangat simpel malah menurut saya. Bila Anda tertarik, silakan mencobanya.

Sudah ada contoh pada alamat unduh, namun belum terdapat cara bagaimana menghubungkan dengan database. Nah, artikel kali ini saya ingin mencontohkan bagaimana menghubungkan Jacwright RestServer dengan database. Kita akan mencobanya pada server lokal (personal computer). Untuk kasus kali ini, saya asumsikan bahwa saya menggunakan XAMPP (silakan membaca artikel berikut ini: Membangun Situs Web).

Mari kita persiapkan pengembangan. Buatlah sebuah folder baru dengan nama myapi pada folder htdocs di lokasi pemasangan XAMMP. Selanjutnya ekstrak berkas zip unduhan dari Jacwright RestServer. Keluarkan semua folder dan berkas dari folder RestServer-master sehingga pada folder myapi kini terdapat folder-folder example dan source. Selanjutnya pindahkan berkas index.php dari folder example ke folder myapi.

 Menyiapkan Pustaka RestServer

Menyiapkan Pustaka RestServer

Buat folder baru dengan nama control di dalam folder myapi. Pindahkan berkas TestController.php dari folder example ke folder control. Pindahkan juga berkas .htaccess dari folder example ke folder myapi.

 Menyiapkan Pengembangan

Menyiapkan Pengembangan

Baik, sampai saat ini persiapan pengambangan sudah selesai. Kita mulai dengan mengedit berkas .htaccess yuk! Ubah menjadi seperti di bawah ini:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /myapi
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
Kemudian ubah berkas index.php menjadi seperti di bawah ini.
<?php
require __DIR__ . '/source/Jacwright/RestServer/RestServer.php';
require __DIR__ . '/control/TestController.php';

$server = new \Jacwright\RestServer\RestServer('debug'); $server->addClass('TestController'); $server->handle();

?>

Sampai di sini webservice sudah bisa Anda uji.

 WebService Saat Dijalankan

WebService Saat Dijalankan

Catatan: saya menggunakan port 8282 untuk service Apache dari XAMPP, biasanya Anda cukup mengakses: localhost/myapi/ jika tidak melakukan perubahan port.

Sekarang kita siapkan untuk penghubung ke database. Buka folder source\Jacwright\RestServer kemudian buat berkas baru dengan nama RestDatabase.php.

 Membuat Berkas RestDatabase.php

Membuat Berkas RestDatabase.php

Tuliskan kode berikut ini pada berkas RestDatabase.php.

<?php
# Name: Database.class.php
# File Description: MySQL Class to allow 
#easy and clean access to common mysql commands
# Author: ricocheting
# Web: http://www.ricocheting.com/
# Update: 2009-12-17
# Version: 2.2.2
# Copyright 2003 ricocheting.com
/*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #-#############################################

namespace Jacwright\RestServer;

class RestDatabase { var $server = ""; //database server var $user = ""; //database login name var $pass = ""; //database login password var $database = ""; //database name var $pre = ""; //table prefix

####################### //internal info var $error = ""; var $errno = 0;

//number of rows affected by SQL query var $affected_rows = 0;

var $link_id = 0; var $query_id = 0;

#-############################################# # desc: constructor public function __construct($server, $user, $pass, $database, $pre=''){ $this->server=$server; $this->user=$user; $this->pass=$pass; $this->database=$database; $this->pre=$pre; }#-#constructor()

#-############################################# # desc: connect and select database using vars above # Param: $new_link can force connect() to open a new link, #even if mysql_connect() was called before with the same parameters function connect($new_link=false) { $this->link_id=@mysql_connect($this->server,$this->user,$this->pass,$new_link); $connect = true; if (!$this->link_id) {//open failed $this->oops("Could not connect to server: <b>$this->server</b>."); $connect = false; }

if(!@mysql_select_db($this->database, $this->link_id)) {//no database $this->oops("Could not open database: <b>$this->database</b>."); $connect = false; }

// unset the data so it can't be dumped $this->server=''; $this->user=''; $this->pass=''; $this->database=''; return $connect; }#-#connect()

#-############################################# # desc: close the connection function close() { if(!@mysql_close($this->link_id)){ $this->oops("Connection close failed."); } }#-#close()

#-############################################# # Desc: escapes characters to be mysql ready # Param: string # returns: string function escape($string) { if(get_magic_quotes_runtime()) $string = stripslashes($string); return @mysql_real_escape_string($string,$this->link_id); }#-#escape()

#-############################################# # Desc: executes SQL query to an open connection # Param: (MySQL query) to execute # returns: (query_id) for fetching results etc function query($sql) { // do query $this->query_id = @mysql_query($sql, $this->link_id);

if (!$this->query_id) { $this->oops("<b>MySQL Query fail:</b> $sql"); return 0; } $this->affected_rows = @mysql_affected_rows($this->link_id);

return $this->query_id; }#-#query()

#-############################################# # desc: fetches and returns results one line at a time # param: query_id for mysql run. if none specified, last used # return: (array) fetched record(s) function fetch_array($query_id=-1) { // retrieve row if ($query_id!=-1) { $this->query_id=$query_id; }

if (isset($this->query_id)) { $record = @mysql_fetch_assoc($this->query_id); }else{ $this->oops("Invalid query_id: <b>$this->query_id</b>. Records could not be fetched."); }

return $record; }#-#fetch_array()

#-############################################# # desc: returns all the results (not one row) # param: (MySQL query) the query to run on server # returns: assoc array of ALL fetched results function fetch_all_array($sql) { $query_id = $this->query($sql); $out = array();

while ($row = $this->fetch_array($query_id, $sql)){ $out[] = $row; }

$this->free_result($query_id); return $out; }#-#fetch_all_array()

#-############################################# # desc: frees the resultset # param: query_id for mysql run. if none specified, last used function free_result($query_id=-1) { if ($query_id!=-1) { $this->query_id=$query_id; } if($this->query_id!=0 && !@mysql_free_result($this->query_id)) { $this->oops("Result ID: <b>$this->query_id</b> could not be freed."); } }#-#free_result()

#-############################################# # desc: does a query, fetches the first row only, frees resultset # param: (MySQL query) the query to run on server # returns: array of fetched results function query_first($query_string) { $query_id = $this->query($query_string); $out = $this->fetch_array($query_id); $this->free_result($query_id); return $out; }#-#query_first()

#-############################################# # desc: does an update query with an array # param: table (no prefix), assoc array with data #(doesn't need escaped), where condition # returns: (query_id) for fetching results etc function query_update($table, $data, $where='1') { $q="UPDATE `".$this->pre.$table."` SET ";

foreach($data as $key=>$val) { if(strtolower($val)=='null') $q.= "`$key` = NULL, "; elseif(strtolower($val)=='now()') $q.= "`$key` = NOW(), "; else $q.= "`$key`='".$this->escape($val)."', "; }

$q = rtrim($q, ', ') . ' WHERE '.$where.';'; //echo $q; return $this->query($q); }#-#query_update()

function query_update_spc($table, $key, $val, $where='1') { $q="UPDATE `".$this->pre.$table."` SET "; $q .= "`$key`='".$this->escape($val)."' "; $q = rtrim($q, ', ') . ' WHERE '.$where.';'; //echo $q; return $this->query($q); }#-#query_update()

#-############################################# # desc: does an insert query with an array # param: table (no prefix), assoc array with data # returns: id of inserted record, false if error function query_insert($table, $data) { $q1 = "SELECT COUNT(*) AS ROWS FROM `".$this->pre.$table."` "; $rows = 0; $datas = $this->query_first($q1); $rows = $datas['ROWS']; $q="INSERT INTO `".$this->pre.$table."` "; $v=''; $n='';

foreach($data as $key=>$val) { $n.="`$key`, "; if(strtolower($val)=='null') $v.="NULL, "; elseif(strtolower($val)=='now()') $v.="NOW(), "; else $v.= "'".$this->escape($val)."', "; }

$q .= "(". rtrim($n, ', ') .") VALUES (". rtrim($v, ', ') .");"; //echo $q; if($this->query($q)){ return true; } else return false; //return $this->query($q); }#-#query_insert() function query_insert_auto($table, $data) { $q1 = "SELECT COUNT(*) AS ROWS FROM `".$this->pre.$table."` "; $rows = 0; $datas = $this->query_first($q1); $rows = $datas['ROWS']; $q="INSERT INTO `".$this->pre.$table."` "; $v=''; $n='';

foreach($data as $key=>$val) { $n.="`$key`, "; if(strtolower($val)=='null') $v.="NULL, "; elseif(strtolower($val)=='now()') $v.="NOW(), "; else $v.= "'".$this->escape($val)."', "; }

$q .= "(". rtrim($n, ', ') .") VALUES (". rtrim($v, ', ') .");"; //echo $q; if($this->query($q)){ return @mysql_insert_id(); } else return false; //return $this->query($q); }#-#query_insert()

#-############################################# # desc: throw an error message # param: [optional] any custom error to display function oops($msg='') { if($this->link_id>0){ $this->error=mysql_error($this->link_id); $this->errno=mysql_errno($this->link_id); } else{ $this->error=mysql_error(); $this->errno=mysql_errno(); } $err = $this->error; echo $err; }#-#oops() }//CLASS Database ################################################ ?>

Karena kita menambahkan obyek baru pada RestServer, pastikan kita mendaftarkan berkas ini. Buka berkas RestServer.php, lihat baris kode ke 28 dan 29. Untuk menambahkan obyek pada namespace Jacwright\RestServer, Anda harus menyisipkan berkas RestDatabase.php ke dalam kelas RestServer. Sisipkan baris kode di bawah ini setelah baris ke 29.
require(__DIR__ . '/RestDatabase.php');
Untuk konfigurasi koneksi ke database, buat folder baru dengan nama config pada folder myapi.

 Membuat Folder config untuk Konfigurasi Database

Membuat Folder config untuk Konfigurasi Database

Sekarang kita siapkan databasenya. Buat database baru dengan nama myapi.

 Membuat Database myapi

Membuat Database myapi

Sebagai contoh, saya membuat dua buah tabel dengan nama: jurusan dan mahasiswa, dengan kolom dan baris seperti pada gambar di bawah ini.

 Tabel Jurusan Beserta Data

Tabel Jurusan Beserta Data

 Tabel Mahasiswa Beserta Data

Tabel Mahasiswa Beserta Data

Berikut ini query SQL nya:

CREATE TABLE IF NOT EXISTS `myapi`;

USE `myapi`;

CREATE TABLE IF NOT EXISTS `jurusan` ( `kode_jurusan` varchar(10) NOT NULL, `nama_jurusan` varchar(25) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `jurusan` (`kode_jurusan`, `nama_jurusan`) VALUES ('BHS', 'Bahasa'), ('IPA', 'Ilmu Pengetahuan Alam'), ('IPS', 'Ilmu Pengetahuan Sosial');

CREATE TABLE IF NOT EXISTS `mahasiswa` ( `nomor_induk` varchar(16) NOT NULL, `nama_mahasiswa` varchar(25) NOT NULL, `kode_jurusan` varchar(10) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `mahasiswa` (`nomor_induk`, `nama_mahasiswa`, `kode_jurusan`) VALUES ('12345001', 'Agung Novian', 'IPA'), ('12345002', 'Fanny Pratiwi', 'IPS'), ('12345003', 'Ajat Jatnika', 'IPA'), ('12345004', 'Azka Banyu Pratama', 'BHS');

ALTER TABLE `jurusan` ADD PRIMARY KEY (`kode_jurusan`);

ALTER TABLE `mahasiswa` ADD PRIMARY KEY (`nomor_induk`);

Sekarang buka folder config yang baru kita buat, kemudian buat sebuah berkas dengan nama dbmyapi.php. Ketikkan kode di bawah ini.
<?php
define('MYAPI_SERVER', "localhost");
define('MYAPI_USER', "root");
define('MYAPI_PASS', "");
define('MYAPI_DATABASE', "myapi");
?>
Silakan sesuaikan konstanta untuk MYAPI_USER dan MYAPI_PASS dengan kondisi pada server database Anda.

Baik, kita sudah punya dua buah tabel pada database. Kita ingin keduanya dapat diakses dengan webservice. Dengan menggunakan Jacwright RestServer, untuk tiap objek tabel yang akan kita akses Anda dapat membuatkan masing-masing sebuah controller object untuk tiap-tiap tabel tersebut. Untuk membuat controller object tersebut silakan buka folder control.

Kita mula dengan membuat obyek untuk tabel jurusan. Buat sebuah berkas dengan nama JurusanController.php. Kemudian tuliskan kode di bawah ini.

<?php

use \Jacwright\RestServer\RestException; use \Jacwright\RestServer\RestDatabase;

class JurusanController {     var $connection = '';          /**      * Returns a JSON string object to the browser when hitting the root of the domain      *      * @url GET /      */     public function main()     {         return "JurusanController";     }          /* Metode untuk koneksi ke database */     function connect(){         $this->connection = new RestDatabase(             MYAPI_SERVER,             MYAPI_USER,             MYAPI_PASS,             MYAPI_DATABASE,             ''         );                  $connect = $this->connection->connect();         return $connect;     }          /* Metode untuk menutup koneksi database */     function close()     {         $this->connection->close();     }          /**      * Metode untuk mengambil data dari tabel jurusan      *      * @url GET /jurusan      * @url GET /jurusan/$kode_jurusan      */     public function getJurusan($kode_jurusan = null)     {         /* variabel untuk menyimpan hasil */         $result = array (             'success' => 0,             'data' => array(                 'total' => 0,                 'rows' => null,             )         );                  /* Menghubungkan ke database */         $connect = $this->connect();                  if ($connect){             $table = 'jurusan';                          /* jika variabel $kode_jurusan tidak ditentukan */             if ($kode_jurusan == null){                 $sql = "SELECT * FROM $table";                              /* jika variabel $kode_jurusan ditentukan */             } else {                 $sql = "SELECT * FROM $table WHERE kode_jurusan='$kode_jurusan'";             }                          $sql .= " ORDER BY kode_jurusan";                                       $rows = null;                          /* Mengeksekusi query */             $records = $this->connection->fetch_all_array($sql);             $total = $this->connection->affected_rows;                          if ($total > 0){                 foreach($records as $record){                     /* Menampung record ke variabel $rows */                     $rows[] = $record;                 }                                  /* Menampung data ke variabel $result */                 $result = array (                         'success' => 1,                         'data' => array(                             'total' => $total,                             'rows' => $rows,                         )                 );             }         }                  /* Mengeluarkan $result */                  return $result;     }

    /**      * Throws an error      *      * @url GET /error      */     public function throwError() {         throw new RestException(401, "Empty password not allowed");     } }

Penjelasannya nanti dulu ya :D Sekarang kembali ke folder myapi, kita edit berkas index.php.
<?php
require __DIR__ . '/source/Jacwright/RestServer/RestServer.php';
require __DIR__ . '/control/TestController.php';

/* Menambahkan berkas untuk konfigurasi database */ require __DIR__ . '/config/dbmyapi.php';

/* Menyisipkan berkas JurusanController.php */ require __DIR__ . '/control/JurusanController.php';

$server = new \Jacwright\RestServer\RestServer('debug'); $server->addClass('TestController');

/* Menambahkan controller object baru */ $server->addClass('JurusanController', 'jurusan');

$server->handle();

Sekarang yuk kita coba dulu!

Silakan ketikkan pada batang alamat dari peramban Anda:

http://localhost/myapi/jurusan/jurusan
 Hasil Pemanggilan Web Service

Hasil Pemanggilan Web Service

Coba pula akses alamat-alamat seperti di bawah ini:

http://localhost/myapi/jurusan/jurusan/ipa
http://localhost/myapi/jurusan/jurusan/ips
http://localhost/myapi/jurusan/jurusan/bhs
Baik, saya mulai penjelasannya ya, dimulai dari berkas index.php. Setiap Anda membuat controller object, Anda harus mendaftarkannya pada berkas index.php. Seperti yang saya lakukan, saya membuat sebuah kelas dengan nama JurusanController yang saya tulis pada berkas JurusanController.php, maka yang harus saya lakukan adalah menyisipkan berkas JurusanController.php:
require __DIR__ . '/control/JurusanController.php';
Pada berkas index.php juga terdapat baris kode:
require __DIR__ . '/config/dbmyapi.php';
Ini untuk menyisipkan berkas konfigurasi database, sehingga compiler PHP mengenali daftar konstanta pada berkas tersebut dan dapat digunakan pada kelas JurusanController. Lihat penggalan kode di bawah ini pada berkas JurusanController.php:
/* Metode untuk koneksi ke database */
  function connect(){
  $this->connection = new RestDatabase(
    MYAPI_SERVER, 
    MYAPI_USER, 
    MYAPI_PASS, 
    MYAPI_DATABASE,
    ''
  );
      $connect = $this->connection->connect();
      return $connect;
  }
Selanjutnya saya menyisipkan baris di bawah ini pada berkas index.php:
$server->addClass('JurusanController', 'jurusan');
Ini berfungsi untuk mendaftarkan kelas JurusanController pada kelas RestServer. Bila Anda perhatikan, ada perbedaan dengan kode untuk mendaftarkan kelas TestController.
$server->addClass('TestController');
Ya, saat mendaftarkan kelas JurusanController saya mengisi nilai parameter $basePath yang disediakan oleh fungsi addClass dengan nilai 'jurusan'. Dampaknya adalah untuk dapat mengakses metode-metode pada kelas JurusanController, saya harus menambahkan part jurusan, seperti contoh pemanggilan di atas.
http://localhost/myapi/jurusan/jurusan
Terdapat dua buah part jurusan memang. Saya sarankan sebaiknya memang begitu, untuk membedakan tiap-tiap controller object, karena kita akan membuat lebih dari satu controller object.

Kita beralih pada penjelasan mengenai kelas JurusanController. Pada kelas tersebut saya membuat fungsi dengan nama getJurusan dengan disertai parameter masukan $kode_jurusan yang bersifat opsional (boleh diisi boleh juga tidak, jika tidak diisi maka nilai parameter tersebut adalah null. Ketika nilai parameter ini adalah null maka program akan menampilkan seluruh record dari tabel jurusan. Sementara jika parameter tidak null maka program akan menampilkan record yang mempunyai nilai kode_jurusan sesuai dengan nilai dari parameter.

Perhatikan bagian komentar di atas deklarasi fungsi getJurusan. Baris-baris beriku ini sangat berperan lho.

* @url GET /jurusan
* @url GET /jurusan/$kode_jurusan
Baris komentar yang diawali dengan kata kunci @url akan dideteksi oleh kelas RestServer dan akan didaftarkan sebagai bentuk alamat url yang dapat diakses. Kata kunci berikutnya adalah GET, ini untuk menentukan metode yang digunakan untuk mengakses alamat url (metode lainnya adalah: POST, PUT, DELETE, OPTIONS, HEAD, TRACE, CONNECT). Kata kunci selanjutnya adalah bagian-bagian yang dapat kita tentukan sendiri.

Berdasarkan perintah dari baris pertama dari contoh komentar di atas, maka fungsi getJurusan dapat Anda panggil dengan menggunakan alamat url:

http://{nama_server}/myapi/jurusan/jurusan
Contoh pemanggilan:
http://localhost/myapi/jurusan/jurusan
Kenapa terdapat part myapi? Lihat pada berkas .htaccess pada baris berikut ini:
RewriteBase /myapi
Kenapa setelah part myapi harus dibubuhi part jurusan? Lihat lagi penjelas di atas pada berkas index.php.

Nah, berdasarkan perintah dari baris ke dua dari contoh komentar di atas * @url GET /jurusan/$kode_jurusan, kita juga dapat mengakses fungsi getJurusan dengan rutin:

http://{nama_server}/myapi/jurusan/jurusan[/kode_jurusan]
Contoh pemanggilan:
http://localhost/myapi/jurusan/jurusan/ips
Menambahkan part ips, ini artinya Anda menyisipkan nilai ips pada fungsi getJurusan yang merupakan nilai untuk parameter $kode_jurusan.

Ingin menambahkan variasi alamat url lain? Silakan saja pada bagian blok komentar, tapi pastikan Anda juga menyiapkan penanganannya pada fungsi getJurusan.

Contoh lain:

/**
 * Metode untuk mengambil data dari tabel jurusan
 *
 * @url GET /jurusan
 * @url GET /jurusan/$kode_jurusan
 * @url GET /jurusan/$kode_jurusan/$nama_jurusan
 * @url GET /lihat
 * @url GET /lihat/$kode_jurusan
 * @url GET /lihat/$kode_jurusan/$nama_jurusan
 */
public function getJurusan($kode_jurusan = null, $nama_jurusan = null)
{
    ...
}
Contoh pemanggilan:
http://localhost/myapi/jurusan/jurusan
http://localhost/myapi/jurusan/jurusan/bhs
http://localhost/myapi/jurusan/jurusan/bhs/bahasa
http://localhost/myapi/jurusan/lihat
http://localhost/myapi/jurusan/lihat/bhs
http://localhost/myapi/jurusan/lihat/bhs/bahasa
Keren kan?

Baik, sampai di sini dulu ya pembaca, karena sudah terlalu panjang artikelnya. :D

Komentar Anda

Komentari