Slim Framework Tutorial : Membuat RESTFul API Sederhana Dengan Slim Framework

Slim Framework

Masih seperti biasa, saya setia nangkring di alfamart dekat rumah sampai pagi untuk mendapatkan secuil koneksi super kencang dari indosat :D. Saking seringnya nangkring disini, saya sampai akrab dengan pegawai dan kasirnya, haha. Yaw lumayan bisa nambah teman, banyak teman banyak rejeki. Bukan cuma cuma banyak anak saja yang banyak rejekinya :p. 3 Hari belakangan ini saya masih penasaran dengan Slim Framework. Micro framework yang berhasil mengalihkan perhatian saya sejenak dari pekerjaan, halaaahh. 

Di tutorial sebelumnya saya sudah membahas sedikit tentang micro framework ini.Di postingan kali ini saya akan coba untuk membahas cara untuk membuat sebuah RESTFul API sederhana dengan memanfaatkan method GET, POST, PUT, dan DELETE. Saya juga tambahkan penggunaan API Key untuk mengakses data yang ada di database. OK deh, langsung aja kita cekibroott ke pembahasannya. Sebelumnya, pembahasan ini gak begitu keren untuk otak lulusan S2, karena hanya dibahas oleh lulusan SMK seperti saya ini. Kalau memang gak keren, monggo gak usah dilanjutkan membacanya :p

1. Buat folder baru di direktori htdocs, dengan nama “api-kota”. Buka command line dan buat sebuah file composer.json menggunakan vim editor.

Membuat file composer.json dengan vim editor

2. Tutup vim editor dan sekarang kita akan mengunduh composer dengan perintah di bawah ini :

curl -s https://getcomposer.org/installer | php -d detect_unicode=off

3. Setelah selesai mengunduh composer, saatnya kita mengeksekusi isi dari file composer.json yang sudah kita buat sebelumnya untuk mengunduh file Slim Framework.

php composer.phar install

4. Di dalam folder “api-kota”, akan muncul folder dengan nama vendor yang berisi file Slim Framework. Masuk ke folder /vendor/slim/slim. Untuk memudahkan proses pengerjaan, ada baiknya kita pindahkan file index.php dan file .htaccess serta folder Slim ke root directory “api-kota. Sehingga susunan direktorinya seperti berikut :

Direktori RESTFull Api

5. Ketika kita membuka alamat localhost/api-kota melalui browser, maka akan muncul welcome screen.

Welcom Screen Slim Framework

6. OK, sekarang kita akan mulai ke proses pembuatan RESTFul API dengan Slim Framework. Studi kasusnya kita akan menampilkan data provinsi dan kabupaten di indonesia. Buat struktur tabel seperti di bawah ini :

CREATE TABLE dlmbg_api_reg (
id_api_reg int(5) NOT NULL AUTO_INCREMENT,
email varchar(50) NOT NULL,
api_key varchar(50) NOT NULL,
PRIMARY KEY (id_api_reg)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE dlmbg_lokasi (
id int(10) NOT NULL,
id_prov int(10) NOT NULL,
nama varchar(100) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `dlmbg_api_reg` VALUES(1, ‘gedesumawijaya@gmail.com’, ‘d2ba5ac651d985a7fad886044d92b5cd’);

7. Buka file index.php dengan editor kesayangan rekan-rekan. Kita akan mencoba untuk membuat sebuah RESTFul API yang memerlukan API Key untuk mengakses data di server. API Key kita simpan di tabel dlmbg_api_reg. Hanya API Key yang terdaftar di tabel tersebut saja yang bisa mendapatkan akses data dari tabel dlmbg_lokasi. Pertama, kita memanggil file Slim/Slim.php dan buat sebuah method koneksi ke database.

<?php
require 'Slim/Slim.php';

\Slim\Slim::registerAutoloader();

$app = new \Slim\Slim();

function getConnection() {
    $dbhost="127.0.0.1";
    $dbuser="root";
    $dbpass="";
    $dbname="db_api_kota";
    $dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $dbh;
}

8. Untuk autentikasi api key, kita buat sebuah method validateApiKey($key) yang nantinya method ini akan kita panggil dengan middleware yang disisipkan melalui routing.

function validateApiKey($key) {
    $sql = "select * FROM dlmbg_api_reg where api_key='".$key."'";
    $db = getConnection();
    $sth = $db->prepare($sql);
    $sth->execute();
    return $sth->rowCount();
}

$authKey = function ($route) {
    $app = \Slim\Slim::getInstance();
    $routeParams = $route->getParams();
    if (validateApiKey($routeParams["key"])==0) {
      $app->halt(401);
    }
};

9. Selanjutnya, kita buat sebuah route baru dengan nama city yang akan menampilkan seluruh data di dalam tabel dlmbg_lokasi. Jika diakses tanpa API Key atau API Key tidak valid, maka akan muncul tampilan kosong di browser. Dan jika diakses melalui extension Chrome Advance REST Client, akan muncul pesan 401 Unauthorized.

401 Unauthorized

Jika diakses dengan API Key yang valid, maka akan muncul pesan 200 Ok. Dan data ditampilkan.

200 OK

$app->get('/city/:key/', $authKey, function () use ($app)  {
    $sql = "select * FROM dlmbg_lokasi";
    try {
        $db = getConnection();
        $stmt = $db->query($sql);
        $data = $stmt->fetchAll(PDO::FETCH_OBJ);
        $db = null;
        $app->response()->header('Content-Type', 'application/json');
        echo '{"data": ' . json_encode($data) . '}';
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}';
    }
});

Jika ingin diakses via terminal/console, bisa menggunakan perintah :

curl -i -X GET http://localhost/api-kota/city/d2ba5ac651d985a7fad886044d92b5cd

10. Sekarang jika ingin mengakses data kabupaten pada provinsi tertentu, kita perlu membuat routing baru.

$app->get('/city/:key/:id/', $authKey, function ($key,$id) use ($app) {
    try {
        $sql = "select * FROM dlmbg_lokasi where id_prov='".$id."'";
        $db = getConnection();
        $stmt = $db->query($sql);
        $data = $stmt->fetchAll(PDO::FETCH_OBJ);

        $db = null;
        $app->response()->header('Content-Type', 'application/json');
        echo '{"data": ' . json_encode($data) . '}';

    } catch (Exception $e) {
        $app->response()->status(400);
        $app->response()->header('X-Status-Reason', $e->getMessage());
    }
});

Contohnya jika ingin mengakses data kabupaten di provinsi Bali, bisa menggunakan perintah berikut via console :

curl -i -X GET http://localhost/api-kota/city/d2ba5ac651d985a7fad886044d92b5cd/51

11. Route dengan method POST kita gunakan untuk menambah data ke dalam tabel. Data dalam format json di push dari client dan ditangkap dengan perintah $app->request(); oleh RESTFul API.

$app->post('/city/:key/', $authKey, function () use ($app)  {
  try {
    $request = $app->request();
    $input = json_decode($request->getBody());
    $sql = "INSERT INTO dlmbg_lokasi (id, id_prov, nama) VALUES (:id, :id_prov, :nama)";

    $db = getConnection();
    $stmt = $db->prepare($sql);
    $stmt->bindParam("id", $input->id);
    $stmt->bindParam("id_prov", $input->id_prov);
    $stmt->bindParam("nama", $input->nama);

    $stmt->execute();
    $data->id = $db->lastInsertId();
    $db = null;
    echo json_encode($data);

  } catch (Exception $e) {
    $app->response()->status(400);
    $app->response()->header('X-Status-Reason', $e->getMessage());
  }
});

curl -i -X POST -H ‘Content-Type: application/json’ -d ‘{“id”: “12000”, “id_prov”: “11”, “nama” : “Timor Leste”}’ http://localhost/api-kota/city/d2ba5ac651d985a7fad886044d92b5cd/

12. Untuk melakukan update terhadap data, kita bisa menggunakan method PUT.

$app->put('/city/:key/:id/', $authKey, function ($key,$id) use ($app)  {
  try {
    $request = $app->request();
    $input = json_decode($request->getBody());
    $sql = "UPDATE dlmbg_lokasi set id_prov=:id_prov, nama=:nama where id='".$id."'";

    $db = getConnection();
    $stmt = $db->prepare($sql);
    $stmt->bindParam("id_prov", $input->id_prov);
    $stmt->bindParam("nama", $input->nama);

    $stmt->execute();
    $data->id = $db->lastInsertId();
    $db = null;
    echo json_encode($input);

  } catch (Exception $e) {
    $app->response()->status(400);
    $app->response()->header('X-Status-Reason', $e->getMessage());
  }
});

curl -i -X PUT -H ‘Content-Tyation/json’ -d ‘{“id”: “12000”, “id_prov”: “0”, “nama” : “Papua Nugini”}’ http://localhost/api-kota/city/d2ba5ac651d985a7fad886044d92b5cd/12000

13. Dan jika ingin menghapus data, kita dapat menggunakan method DELETE

$app->delete('/city/:key/:id/', $authKey, function ($key,$id) use ($app) {
  try {
    $sql = "DELETE FROM dlmbg_lokasi WHERE id='".$id."'";
    $db = getConnection();
    $stmt = $db->prepare($sql);
    $stmt->bindParam("id", $id);
    $stmt->execute();
    $db = null;

  } catch (Exception $e) {
    $app->response()->status(400);
    $app->response()->header('X-Status-Reason', $e->getMessage());
  }
});

curl -i -X DELETE http://localhost/api-kota/city/d2ba5ac651d985a7fad886044d92b5cd/12000

14. Berikut kode selengkapnya :

<?php
require 'Slim/Slim.php';

\Slim\Slim::registerAutoloader();

$app = new \Slim\Slim();

function getConnection() {
    $dbhost="127.0.0.1";
    $dbuser="root";
    $dbpass="";
    $dbname="db_api_kota";
    $dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $dbh;
}

function validateApiKey($key) {
    $sql = "select * FROM dlmbg_api_reg where api_key='".$key."'";
    $db = getConnection();
    $sth = $db->prepare($sql);
    $sth->execute();
    return $sth->rowCount();
}

$authKey = function ($route) {
    $app = \Slim\Slim::getInstance();
    $routeParams = $route->getParams();
    if (validateApiKey($routeParams["key"])==0) {
      $app->halt(401);
    }
};

$app->get('/city/:key/', $authKey, function () use ($app)  {
    $sql = "select * FROM dlmbg_lokasi";
    try {
        $db = getConnection();
        $stmt = $db->query($sql);
        $data = $stmt->fetchAll(PDO::FETCH_OBJ);
        $db = null;
        $app->response()->header('Content-Type', 'application/json');
        echo '{"data": ' . json_encode($data) . '}';
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}';
    }
});

$app->get('/city/:key/:id/', $authKey, function ($key,$id) use ($app) {
    try {
        $sql = "select * FROM dlmbg_lokasi where id_prov='".$id."'";
        $db = getConnection();
        $stmt = $db->query($sql);
        $data = $stmt->fetchAll(PDO::FETCH_OBJ);

        $db = null;
        $app->response()->header('Content-Type', 'application/json');
        echo '{"data": ' . json_encode($data) . '}';

    } catch (Exception $e) {
        $app->response()->status(400);
        $app->response()->header('X-Status-Reason', $e->getMessage());
    }
});

$app->post('/city/:key/', $authKey, function () use ($app)  {
  try {
    $request = $app->request();
    $input = json_decode($request->getBody());
    $sql = "INSERT INTO dlmbg_lokasi (id, id_prov, nama) VALUES (:id, :id_prov, :nama)";

    $db = getConnection();
    $stmt = $db->prepare($sql);
    $stmt->bindParam("id", $input->id);
    $stmt->bindParam("id_prov", $input->id_prov);
    $stmt->bindParam("nama", $input->nama);

    $stmt->execute();
    $data->id = $db->lastInsertId();
    $db = null;
    echo json_encode($data);

  } catch (Exception $e) {
    $app->response()->status(400);
    $app->response()->header('X-Status-Reason', $e->getMessage());
  }
});

$app->put('/city/:key/:id/', $authKey, function ($key,$id) use ($app)  {
  try {
    $request = $app->request();
    $input = json_decode($request->getBody());
    $sql = "UPDATE dlmbg_lokasi set id_prov=:id_prov, nama=:nama where id='".$id."'";

    $db = getConnection();
    $stmt = $db->prepare($sql);
    $stmt->bindParam("id_prov", $input->id_prov);
    $stmt->bindParam("nama", $input->nama);

    $stmt->execute();
    $data->id = $db->lastInsertId();
    $db = null;
    echo json_encode($input);

  } catch (Exception $e) {
    $app->response()->status(400);
    $app->response()->header('X-Status-Reason', $e->getMessage());
  }
});

$app->delete('/city/:key/:id/', $authKey, function ($key,$id) use ($app) {
  try {
    $sql = "DELETE FROM dlmbg_lokasi WHERE id='".$id."'";
    $db = getConnection();
    $stmt = $db->prepare($sql);
    $stmt->bindParam("id", $id);
    $stmt->execute();
    $db = null;

  } catch (Exception $e) {
    $app->response()->status(400);
    $app->response()->header('X-Status-Reason', $e->getMessage());
  }
});

$app->run();

Nah, cukup mudah kan untuk membuat sebuah RESTFul API dengan Slim Framework,,,?? Sekarang memang lagi keren-keren’nya aplikasi yang dibangun dengan RESTFul API, karena dengan begitu target aplikasi di client bisa bermacam-macam. Bisa dibuat ke aplikasi mobile, desktop bahkan web. Sebenarnya pada aplikasi ini bisa kita tambahkan autentikasi tambahan, dimana user yang ingin mengakses data dari REST API harus login terlebih dahulu. Monggo kawan-kawan yang menambahkan. Sebenarnya tadi sudah sempat saya tambahkan, cuma agak kesulitan mencobanya melalui extension chrome Advance Rest Client.

Di tutorial selanjutnya, saya akan mencoba untuk membuat aplikasi client yang mengambil data dari REST API ini. OK deh, semoga postingan ini bisa bermanfaat untuk rekan-rekan yang sedang belajar membuat RESTFul API dengan Slim Framework 🙂

“Stay Foolish, Stay Hungry”

Happy Blogging and Keep Coding

Cheerrrss….!!!!

7 comments

  1. Miftah Aris Setiawan Reply

    bro misalkan routes nya pgn saya ganti misalkan menjadi $app->get(‘/city/:key?id={:id}&nama={:nama}’) itu gimana caranya ya? saya udh coba tp not found mulu. thx

  2. tyo Reply

    gan, ada tutorial RESTful buat di codeigniter.. mohon di bantu gan..