Memuat RESTful API dengan PHP MySQL dan Framework Slim Husni.Trunojoyo.ac.id
Slim adalah suatu framework mikro PHP yang open source dan berfitur penuh yang dapat membantu kita untuk dengan cepat menuliskan aplikasi dan API web yang berdayaguna meskipun sederhana. Slim hadir dengan arsitektur middleware dan URL dispatcher yang canggih yang membuatnya ideal untuk memprototipekan situs web statis dan API. Framework ini mendukung semua metode HTTP (GET, POST, PUT dan DELETE). Artikel ini merupakan rangkuman dari kegiatan pengujian kemampuan dasar dari framework Slim secara detail, mengilustrasikan bagaimana kita dapat menggunakannya untuk dengan cepat membangun dan mendeploy suatu REST API dengan dukungan otentikasi dan banyak format request/response.
Instalasi Slim Jika kita menggunakan Composer, suatu manajer dependensi PHP, cukup jalankan perintan berikut: php composer.phar create-project slim/slim-skeleton [my-app-name] atau composer create-project slim/slim-skeleton [my-app-name] Silakan ganti [my-app-name] dengan nama direktori yang diinginkan untuk aplikasi baru kita, misalnya wslim. Perintah diatas akan membuat suatu proyek menggunakan aplikasi Slim-Skeleton dan hasilnya adalah suatu struktur direktori yang seperti gambar 1 dan telah berisi file-file Slim untuk pengembangan aplikasi atay layanan web. C:\xampp\htdocs>composer create-project slim/slim-skeleton wslim Installing slim/slim-skeleton (3.0.2) - Installing slim/slim-skeleton (3.0.2) Downloading: 100% Created project in wslim Loading composer repositories with package information Updating dependencies (including require-dev) ...
1
Gambar 1. Struktur direktori awal yang diberikan oleh aplikasi Slim-Skeleton Sekarang kita dapat menjalankan proyek orisinil ini memanfaatkan web server bawaan (built-in) PHP atau di bawah kendali web server yang lebih baik (misalnya Apache). cd [my-app-name]; php -S 0.0.0.0:8080 -t public public/index.php C:\xampp\htdocs>cd wslim C:\xampp\htdocs\wslim>php -S 0.0.0.0:8080 -t public public/index.php PHP 7.0.5 Development Server started at Mon Jun 13 04:57:29 2016 Listening on http://0.0.0.0:8080 Document root is C:\xampp\htdocs\wslim\public Press Ctrl-C to quit. Kita dapat melihat aplikasi yang dihasilkan oleh Slim-Skeleton dengan mengarahkan web browser ke alamat http://localhost/wslim/public/, http://locahost:8080/ atau http://127.0.0.1:8080/. Alamat pertama adalah URL default dari perspektif Apache (XAMPP di Windows), sedangkan 2 URL terakhir adalah hasil eksekusi web server built-in PHP. Hasilnya adalah seperti pada gambar 2.
Gambar 2. Tampilan aplikasi orisinil yang dibangkitkan Slim-Skeleton 2
Database dan Tabel Berikan nama untuk database, misalnya db_wslim dan jalankan perintah SQL berikut untuk membuat tabel tb_tasks: 1 -2 -- Table structure for `tb_tasks` 3 -4 CREATE TABLE IF NOT EXISTS `tb_tasks` ( 5
`id` int(11) NOT NULL,
6
`task` varchar(200) NOT NULL,
7
`status` tinyint(1) NOT NULL DEFAULT '1',
8
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
9 ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 10 11 ALTER TABLE `tb_tasks` ADD PRIMARY KEY (`id`); 12 ALTER TABLE `tb_tasks` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; Masukkan beberapa baris (record) data contoh ke dalam tabel tb_tasks tersebut. 1
INSERT INTO `tb_tasks` (`id`, `task`, `status`, `created_at`) VALUES
2
(1, 'Menemukan bugs', 1, '2016-04-10 23:50:40'),
3
(2, 'Mereview kode program', 1, '2016-04-10 23:55:40'),
4
(3, 'Membetulkan bugs getXYZ', 1, '2016-04-11 01:45:44'),
5
(4, 'Merefaktor kode', 1, '2016-04-11 13:50:40'),
6
(5, Meletakkan ke server produksi', 1, '2016-04-13 10:50:50');
Konfigurasi Database Buka file src/settings.php dan konfigurasikan setingan database kita dengan menambahkan atau mengedit array konfigurasi database. 1
// Database connection settings
2
"db" => [
3
"host" => "locahost",
4
"dbname" => "nama_database_kita ",
5
"user" => "nama_user_mysql ",
6
"pass" => "password_user_mysql "
7
], 3
Contoh isi file src/settings.php adalah sebagai berikut: [ 'displayErrorDetails' => true, // set to false in production // Renderer settings 'renderer' => [ 'template_path' => __DIR__ . '/../templates/', ], // Monolog settings 'logger' => [ 'name' => 'slim-app', 'path' => __DIR__ . '/../logs/app.log', ], // Database settings 'db' => [ 'host' => 'localhost', 'dbname' => 'db_wslim', 'user' => 'root', 'pass' => '', ], ], ]; Sekarang bukan file src/dependencies.php dan konfigurasikan pustaka databasenya. Ada banyak pustaka database yang tersedia untuk PHP, tetapi contoh ini hanya menggunakan PDO – ini tersedia di dalam PHP sebagai standard sehingga sangat berguna untuk setiap proyek atau kita dapat menggunakan pustaka sendiri dengan mengadaptasikan contoh di bawah ini. Kode berikut ini adalah contoh yang memperlihatkan konfigurasi pustaka database yang akan kita gunakan selama tutorial ini (letakkan di bagian paling bawah di dalam file src/dependencies.php): 1 // PDO database library 2 $container['db'] = function ($c) { 3
$settings = $c->get('settings')['db'];
4
$pdo = new PDO("mysql:host=" . $settings['host'] . ";dbname=" . $settings['dbname'],
5
$settings['user'], $settings['pass']);
6
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
7
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
8
return $pdo;
9 }; Kita akan mengimplementasikan fungsi-fungsi API berikut: 4
Metode URL
Aksi yang diharapkan
GET
/api/todos
Retrieve semua todos
GET
/api/todos/search/bug Mencari todos dengan ‘bug’ di dalam namanya
GET
/api/todo/1
Retrieve todo dengan id == 1
POST
/api/todo
Menambahkan suatu todo baru
PUT
/api/todo/1
Update todo dengan id == 1
DELETE
/api/todo/1
Delete todo dengan id == 1
Implementasi API Call dengan Slim Aplikasi Slim telah up dan berjalan dengan koneksi database, saatnya kita perlu mengelola todos dalam database tersebut. Mendapatkan Daftar Tugas (Todos List) Kita akan membuat suatu rute (route) baru sehingga ketika seorang pengguna menulis /todos maka aplikasi ini akan mengembalikan daftar semua tigas dalam format JSON. 1 // mendapatkan semua todos 2
$app->get('/todos', function ($request, $response, $args) {
3
$sth = $this->db->prepare("SELECT * FROM tb_tasks ORDER BY task");
4
$sth->execute();
5
$todos = $sth->fetchAll();
6
return $this->response->withJson($todos);
7
});
Secara garus besar fungsi ini mengembalikan semua informasi todos sebagaimana dapat kita lihat di dalam query. Bagaimana mengakses API ini? Panggil URL http://localhost:8080/todos. Mendapatkan Tugas Tertentu Kita akan membuat suatu rute baru sehingga manakala pengguna menuliskan /todo/{id} maka aplikasi akan mengembalikan satu todo (sesuai id) dalam format JSON. 1
// meretrieve todo dengan id tertentu
2
$app->get('/todo/[{id}]', function ($request, $response, $args) {
3
$sth = $this->db->prepare("SELECT * FROM tb_tasks WHERE id=:id");
4
$sth->bindParam("id", $args['id']);
5
$sth->execute();
6
$todos = $sth->fetchObject(); 5
7 8
return $this->response->withJson($todos); });
Fungsi ini memeriksa record dari is yang diberikan dan mengembalik detail dari id tersebut jika ditemukan. Cara memanggil API ini adalah dengan mengakses URL http://localhost:8080/todo/1. Mencari Tugas Berdasarkan Nama Kita akan membuat suatu rute baru sedemikian hingga ketika pengguna menuliskan /todos/search/{Query}, aplikasi akan mengembalikan suatu daftar dari semua todos yang cocok dengan Query dalam format JSON. 1
// mencari todo yang cocok dengan keyword Query di dalam namanya (kolom task)
2
$app->get('/todos/search/[{query}]', function ($request, $response, $args) {
3
$sth = $this->db->prepare("SELECT * FROM tb_tasks WHERE UPPER(task) LIKE :query ORDER BY task");
4
$query = "%".$args['query']."%";
5
$sth->bindParam("query", $query);
6
$sth->execute();
7
$todos = $sth->fetchAll();
8
return $this->response->withJson($todos);
9
});
Fungsi ini mencari di dalam database query yang dimasukkan pengguna. Contoh cara memanggil API ini adalah mengakses URL berbentuk http://localhost:8080/search/bug. Menambahkan Tugas Baru Kita harus membuatkan suatu rute baru sedemikian hingga manakala pengguna mengirimkan suatu request POST ke /todo dengan data yang diperlukan, aplikasi akan menambahkan record baru ke dalam database. 1
// Menambahkan todo baru
2
$app->post('/todo', function ($request, $response) {
3
$input = $request->getParsedBody();
4
$sql = "INSERT INTO tb_tasks (task) VALUES (:task)";
5
$sth = $this->db->prepare($sql);
6
$sth->bindParam("task", $input['task']);
7
$sth->execute();
8
$input['id'] = $this->db->lastInsertId();
9
return $this->response->withJson($input);
10
});
API ini menerima permintaan POST dan menyisipkan data yang di-submit ke dalam database. Cara pemanggilan API ini dalah mengakses URL http://localhost:8080/todo.
6
Menghapus Tugas Tertentu Kita perlu membuat suatu rute baru sehingga ketika pengguna mengirimkan suatu permintaan DELETE berbentuk /todo/{id}, aplikasi akan menghapus record yang sesuai dengan id tersebut dari dalam database. 1
// menghapus suatu todo sesuai dengan id-nya
2
$app->delete('/todo/[{id}]', function ($request, $response, $args) {
3
$sth = $this->db->prepare("DELETE FROM tb_tasks WHERE id=:id");
4
$sth->bindParam("id", $args['id']);
5
$sth->execute();
6
$todos = $sth->fetchAll();
7
return $this->response->withJson($todos);
8
});
Mengupdate Tugas Tertentu Kita harus membuat suatu rute baru sehingga ketika pengguna mengirimkan permintaan PUT berbentuk /todo/{id} dengan data yang disyaratkan maka aplikasi akan mengudate suatu record berdasarkan kecocokan parameter di dalam database. 1
// mengupdate todo sesuai dengan id-nya
2
$app->put('/todo/[{id}]', function ($request, $response, $args) {
3
$input = $request->getParsedBody();
4
$sql = "UPDATE tb_tasks SET task=:task WHERE id=:id";
5
$sth = $this->db->prepare($sql);
6
$sth->bindParam("id", $args['id']);
7
$sth->bindParam("task", $input['task']);
8
$sth->execute();
9
$input['id'] = $args['id'];
10
return $this->response->withJson($input);
11
});
API ini menerima permintaan PUT dan mengupdate data yang disubmitkan ke dalam database. Cara memanggil API ini adalah mengakses URL berbentuk http://localhost:8080/ todo/{id}.
7
Kode Web Service Lengkap Di bawah ini adalah isi file src/routes.php lengkap (versi akhir): 1 $app->group('/api', function () use ($app) { 2 3 // mengambil semua tugas (todos) 4 $app->get('/todos', function ($request, $response, $args) { 5 $sth = $this->db->prepare("SELECT * FROM tb_tasks ORDER BY task"); 6 $sth->execute(); 7 $todos = $sth->fetchAll(); 8 return $this->response->withJson($todos); 9 }); 10 11 // mengambil detail tugas dengan id tertentu 12 $app->get('/todo/[{id}]', function ($request, $response, $args) { 13 $sth = $this->db->prepare("SELECT * FROM tb_tasks WHERE id=:id"); 14 $sth->bindParam("id", $args['id']); 15 $sth->execute(); 16 $todos = $sth->fetchObject(); 17 return $this->response->withJson($todos); 18 }); 19 20 // mencari tugas dengan term pencarian tertentu di dalam namanya 21 $app->get('/todos/search/[{query}]', function ($request, $response, $args) { 22 $sth = $this->db->prepare("SELECT * FROM tb_tasks WHERE UPPER(task) LIKE :query ORDER BY task"); 23 $query = "%".$args['query']."%"; 24 $sth->bindParam("query", $query); 25 $sth->execute(); 26 $todos = $sth->fetchAll(); 27 return $this->response->withJson($todos); 28 }); 29 30 // menambahkan suatu tugas baru 31 $app->post('/todo', function ($request, $response) { 32 $input = $request->getParsedBody(); 33 $sql = "INSERT INTO tb_tasks (task) VALUES (:task)"; 34 $sth = $this->db->prepare($sql); 35 $sth->bindParam("task", $input['task']); 36 $sth->execute(); 37 $input['id'] = $this->db->lastInsertId(); 38 return $this->response->withJson($input); 39 }); 40 41 // menghapus suatu tugas dengan id tertentu 42 $app->delete('/todo/[{id}]', function ($request, $response, $args) { 43 $sth = $this->db->prepare("DELETE FROM tb_tasks WHERE id=:id"); 44 $sth->bindParam("id", $args['id']); 45 $sth->execute(); 46 $todos = $sth->fetchAll(); 47 return $this->response->withJson($todos); 48 });
8
49 // mengupdate tugas dengan id tertentu 50 $app->put('/todo/[{id}]', function ($request, $response, $args) { 51 $input = $request->getParsedBody(); 52 $sql = "UPDATE tb_tasks SET task=:task WHERE id=:id"; 53 $sth = $this->db->prepare($sql); 54 $sth->bindParam("id", $args['id']); 55 $sth->bindParam("task", $input['task']); 56 $sth->execute(); 57 $input['id'] = $args['id']; 58 return $this->response->withJson($input); 59 }); 60 61 });
Bagaimana cara memanfaatkan kumpulan API atau web service lengkap di atas? Untuk percobaan, hanya untuk sekedar mengetahui apakah web service telah berjalan dengan baik, kita dapat menggunakan ekstensi Postman yang hadir pada web browser Google Chrome. Jika menggunakan Firefox, maka dapat digunakan Add On REST Client. Cara paling jelas dan ril adalah menuliskan kode dalam bahasa pemrograman tertentu (PHP, JavaScript, Java atau Python) yang difungsikan sebagai client dari web service yang telah kita dibuat di atas. Fungsi utama dari aplikasi client adalah mengirimkan request ke penyedia web service dan kemudian mengolah data berformat JSON yang diterimanya dari server. Bagaimana mengolah data JSON? Setidaknya dasar mengenai Array Asosiatif sangat diperlukan. Selamat belajar lebih lanjut mengenai Web Service....
9