Dasar-dasar Pembuatan Application Programming Interface (API)

Application Programming Interface (API) biasanya dibangun oleh pengembang untuk menjembatani frontend dan backend.

Seme Framework memiliki fungsionalitas yang dapat mendukung untuk membangun API.

Dalam tutorial ini Anda akan belajar tentang bagaimana:

  • Mempersiapkan hasil keluaran berupa JSON dengan menggunakan library SEME_JSON.
  • Membuat file Core controller supaya pembuatan kode yang berulang bisa dikurangi.
  • Mengumpulkan dan memasukkan data formulir dan permintaan URI.
  • Lakukan proses Create, Retrieve, Update and Delete (CRUD) ke database.
  • Pengujian hasil dari pembuatan API

Prasyarat

Untuk hasil terbaik dari tutorial ini, Anda harus mengatur atau menginstal item berikut:

Jika sudah yakin, mari kita mulai!

Struktur file dan direktori

Sebelum kita melanjutkan ke tahap coding, kita harus belajar tentang direktori dan struktur hasil api yang kita gunakan untuk membangun API.

Struktur Direktori

Berikut adalah struktur yang harus kita ketahui dan digunakan.

- app
-- controller
--- api
---- home.php
---- apikey.php
-- model
--- api
---- a_apikey_model.php

Kita harus memisahkan controller dan model juga untuk menghindari kesalahan dengan menambahkan direktori baru ke model dan controller.

Struktur respons API

Ada banyak format standar untuk struktur respons API, tetapi kami menggunakan struktur API paling dasar pada tutorial ini.

{
  "status": 200,
  "message": "Success",
  "data": []
}

Saat membuat API, kita tidak membutuhkan view, karena hasil API atau tampilan akan diproses langsung melalui kelas controller.

Fase Pengkodean (Ngoding)

Setelah memahami strukturnya, saatnya mengimplementasikan kode-kode tersebut.

Menentukan Respon atau hasil keluaran API

Pertama-tama kita harus membuat respons API default untuk menguji fungsionalitas dasar dan struktur hasil api dasar.

Buat direktori baru bernama api di dalam app/controller/.

Kemudian setelah itu dalam direktori baru tadi buat file baru bernama home.php.

<?php
class Home extends SENE_Controller
{
  public function __construct()
  {
    parent::__construct();
    $this->lib("sene_json_engine", "json");
  }
  public function index(){
    $data = array();
    $data['status'] = 404;
    $data['message'] = 'Not found';
    $data['data'] = array();
    $this->json->out($data);
  }
}

Kelas controller yang berisi kode ini merupakan kelas yang disusun dengan kode dasar untuk pembuatan API.

Untuk menguji fungsionalitasnya, cukup buka http://localhost/seme_framework/api/ melalui browser dan akan menghasilkan respon not found dengan status 404.

Membuat kelas Model

Kita harus membuat model untuk berkomunikasi antara PHP Server dan Database server.

Buat direktori baru bernama api di dalam app/model/. Kemudian buat file baru bernama a_apikey_model.php di dalam direktori baru tersebut.

Dalam model kita harus menambahkan beberapa metode seperti insert, update, delete, get by id, get all data, dan metode lainnya.

<?php
class A_ApiKey_Model extends SENE_Model
{
  public $tbl = 'a_apikey';
  public $tbl_as = 'ak';

  public function __construct()
  {
    parent::__construct();
    $this->db->from($this->tbl, $this->tbl_as);
  }

  /**
  * Start transaction
  * @return boolean      1 success, false failed
  */
  public function trans_start()
  {
    $r = $this->db->autocommit(0);
    if ($r) {
      return $this->db->begin();
    }
    return false;
  }

  /**
  * Commit transaction
  * @return boolean      1 success, false failed
  */
  public function trans_commit()
  {
    return $this->db->commit();
  }

  /**
  * Rollback transaction
  * @return boolean      1 success, false failed
  */
  public function trans_rollback()
  {
    return $this->db->rollback();
  }

  /**
  * Close / End transaction
  * @return boolean      1 success, false failed
  */
  public function trans_end()
  {
    return $this->db->autocommit(1);
  }

  /**
  * get last ID before insert
  * @param  int $nation_code    Nation Code or Country Code
  * @return int                 last id, 0 failed
  */
  public function getLastId($nation_code)
  {
    $this->db->select_as("COALESCE(MAX($this->tbl_as.id),0)+1", "last_id", 0);
    $this->db->from($this->tbl, $this->tbl_as);
    $this->db->where("nation_code", $nation_code);
    $d = $this->db->get_first('', 0);
    if (isset($d->last_id)) {
      return $d->last_id;
    }
    return 0;
  }

  /**
  * Insert data to a table row
  * @param  array   $di    key value pair for inserting data to a table
  * @return boolean        1 success, false failed
  */
  public function set($di)
  {
    return $this->db->insert($this->tbl, $di);
  }

  /**
  * Update data in a table row
  * @param  array   $nation_code     Nation Code or Country Code
  * @param  array   $id              ID from a table
  * @return boolean                  1 success, false failed
  */
  public function update($nation_code, $id, $du)
  {
    $this->db->where('nation_code', $nation_code);
    $this->db->where('id', $id);
    return $this->db->update($this->tbl, $du);
  }

  /**
  * Delete data in a table row
  * @param  array   $nation_code     Nation Code or Country Code
  * @param  array   $id              ID from a table
  * @return boolean                  1 success, false failed
  */
  public function del($nation_code, $id)
  {
    $this->db->where('nation_code', $nation_code);
    $this->db->where('id', $id);
    return $this->db->delete($this->tbl);
  }

  /**
  * Retrieve all rows
  * @return array        Array of object
  */
  public function get()
  {
    return $this->db->get();
  }

  /**
  * [getById description]
  * @param  int    $nation_code Nation Code or Country Code
  * @param  int    $id          ID from a table
  * @return object              Success if return Single row data object, otherwise return empty object
  */
  public function getById($nation_code,$id)
  {
    $this->db->where('nation_code', $nation_code);
    $this->db->where('id', $id);
    return $this->db->get_first();
  }
}

Membuat kelas Controller

Setelah membuat kelas model, sekarang kita akan mencoba membuat kelas controller. Kelas controller ini nantinya akan digunakan untuk mengeksekusi CRUD.

Tentang CRUD

CRUD merupakan istilah untuk Create, Retrieve, Update, Delete. Biasanya diartikan sebagai proses dasar dalam penarikan / penampilan data, penghapusan data, perubahan data ataupun penghapusan data.

CRUD juga biasanya digunakan sebagai fungsi dasar dalam pengoperasian aplikasi atau pembuatan aplikasi.

<?php
class ApiKey extends SENE_Controller
{
  public function __construct()
  {
    parent::__construct();
    $this->load("a_apikey_model", "aakm");
    $this->lib("sene_json_engine", "json");
  }
  public function index(){
    $data = array();
    $data['status'] = 200;
    $data['message'] = 'Success';
    $data['data'] = $this->aakm->get();
    $this->json->out($data);
  }

  public function detail($id){
    $data = array();
    $id = (int) $id;
    if($id<=0){
      $data['status'] = 800;
      $data['message'] = 'invalid ID';
      $this->json->out($data);
    }

    $aakm = $this->aakm->getById($id);
    if(!isset($aakm->id)){
      $data['status'] = 804;
      $data['message'] = 'Data with supplied ID not found';
      $this->json->out($data);
    }else{
      $data['status'] = 200;
      $data['message'] = 'Success';
      $data['data'] = $aakm;
      $this->json->out($data);
    }
  }

  public function create(){
    $data = array();
    $data['status'] = 549;
    $data['message'] = 'one or more parameter are required';
    $data['data'] = array();

    //collect input
    $nation_code = $this->input->post('nation_code');
    $code = $this->input->post('code');
    $name = $this->input->post('name');
    $is_active = (int) $this->input->post('is_active');

    //validation
    if(strlen($nation_code)==0){
      $data['status'] = 801;
      $data['message'] = 'invalid nation_code';
      $this->json->out($data);
    }
    if(strlen($code)==0){
      $data['status'] = 801;
      $data['message'] = 'invalid code';
      $this->json->out($data);
    }
    if(strlen($name)==0){
      $data['status'] = 802;
      $data['message'] = 'invalid name';
      $this->json->out($data);
    }
    if($is_active<0){
      $data['status'] = 803;
      $data['message'] = 'invalid is_active';
      $this->json->out($data);
    }

    //transaction open
    $this->aakm->trans_start();

    //data input
    $di = array();
    $di['nation_code'] = $nation_code;
    $di['id'] = $this->aakm->getLastId($nation_code);
    $di['code'] = $code;
    $di['name'] = $name;
    $di['cdate'] = 'NOW()';
    $di['ldate'] = 'NOW()';
    $di['is_active'] = $is_active;

    $res = $this->aakm->set($di);
    if($res){
      $data['status'] = 200;
      $data['message'] = 'success';
      $data['data'] = $this->aakm->get();
      $this->aakm->trans_commit();
    }else{
      $data['status'] = 900;
      $data['message'] = 'insert data failed';
      $this->aakm->trans_rollback();
    }

    //transaction closed
    $this->aakm->trans_end();

    //render response
    $this->json->out($data);
  }

  public function edit($nation_code,$id){
    $data = array();
    $data['status'] = 549;
    $data['message'] = 'one or more parameter are required';
    $data['data'] = array();

    $nation_code = $this->input->post('nation_code');
    if(strlen($nation_code)==0){
      $data['status'] = 801;
      $data['message'] = 'invalid nation_code';
      $this->json->out($data);
    }

    $id = (int) $id;
    if($id<=0){
      $data['status'] = 800;
      $data['message'] = 'invalid ID';
      $this->json->out($data);
    }

    $aakm = $this->aakm->getById($nation_code,$id);
    if(!isset($aakm->id)){
      $data['status'] = 804;
      $data['message'] = 'Data with supplied ID not found';
      $this->json->out($data);
    }

    //collect input
    $code = $this->input->post('code');
    $name = $this->input->post('name');
    $is_active = (int) $this->input->post('is_active');

    //validation
    if(strlen($code)==0){
      $data['status'] = 801;
      $data['message'] = 'invalid code';
      $this->json->out($data);
    }
    if(strlen($name)==0){
      $data['status'] = 802;
      $data['message'] = 'invalid name';
      $this->json->out($data);
    }
    if($is_active<0){
      $data['status'] = 803;
      $data['message'] = 'invalid is_active';
      $this->json->out($data);
    }

    //data update
    $du = array();
    $du['nation_code'] = $nation_code;
    $du['code'] = $code;
    $du['name'] = $name;
    $du['ldate'] = 'NOW()';
    $du['is_active'] = $is_active;

    $res = $this->aakm->update($nation_code,$id,$du);
    if($res){
      $data['status'] = 200;
      $data['message'] = 'success';
      $data['data'] = $this->aakm->get();
    }else{
      $data['status'] = 900;
      $data['message'] = 'update data failed';
    }
    $this->json->out($data);
  }

  public function delete($nation_code,$id){
    $data = array();
    $data['status'] = 549;
    $data['message'] = 'one or more parameter are required';
    $data['data'] = array();

    $nation_code = $this->input->post('nation_code');
    if(strlen($nation_code)==0){
      $data['status'] = 801;
      $data['message'] = 'invalid nation_code';
      $this->json->out($data);
    }

    $id = (int) $id;
    if($id<=0){
      $data['status'] = 800;
      $data['message'] = 'invalid ID';
      $this->json->out($data);
    }

    $aakm = $this->aakm->getById($nation_code,$id);
    if(!isset($aakm->id)){
      $data['status'] = 804;
      $data['message'] = 'Data with supplied ID not found';
      $this->json->out($data);
    }

    $res = $this->aakm->del($nation_code,$id);
    if($res){
      $data['status'] = 200;
      $data['message'] = 'success';
      $data['data'] = $this->aakm->get();
    }else{
      $data['status'] = 900;
      $data['message'] = 'delete data failed';
    }
    $this->json->out($data);
  }
}

Menguji hasil pembuatan API

Setelah menyelesaikan kode, kita dapat menguji kode dengan menggunakan Postman. Apabila anda sudah memiliki kemapuan berlebih, bisa juga dicoba dengan menggunakan runner test sendiri ataupun aplikasi testing API lainnya.

Seme Framework telah mendukung pembuatan test runner sendiri untuk menguji API.

Menguji API untuk List Data

Untuk menguji daftar kunci api, Anda dapat membuka url langsung di browser Anda untuk http://localhost/seme_framework/api/apikey/.

Tapi, untuk fungsi lain anda harus mengujinya dengan menggunakan runner atau postman.

Berikut adalah beberapa contoh untuk menguji API melalui Postman.

Create (Menambahkan Data)

Untuk menambahkan data dengan menggunakan postman, dapat dilihat dari screenshot dibawah ini.

Edit (Perubahan data)

Untuk melakukan perubahan data dengan menggunakan postman, dapat dilihat dari screenshot dibawah ini.

Delete (Menghapus data)

Untuk melakukan penghapus data dengan menggunakan postman, dapat dilihat dari screenshot dibawah ini.

Selamat, tutorial dasar API sudah selesai.

Jika Anda menghadapi masalah, jangan ragu untuk membuat issue di Github Seme Framework atau menghubungi saya secara langsung.