Basic API

Application Programming Interface (API) ussually built by developer for bridging frontend and backend.

Seme Framework has functionality that can support for building API.

In this tutorial you will learn about how to:

  • Setup the json output using library.
  • Create core controller for reusable function.
  • Collect and input from form data and URI request.
  • Do the Create, Retrieve, Update and Delete (CRUD) process to database.
  • Test the API.

Prerequisited

For best result of this tutorial, you have to setup or installed the followings item:

Okay, lets get started!

The Structure

Before we proceed to coding phase, we have to learn about the directory and api result structure that we used to building the API.

Directory Structure

Here is the structure that we have to use.

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

We have to separated controller and the model too for avoiding mistake by add new directory to model and controller.

API response structure

There is many standard format for API response structure, but we use the most basic API structure on this tutorial.

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

While creating API, we doesn't need the view, because API result will be rendered on controller.

Coding Phase

After understranding the structure, its time to implement the codes.

Create the default API

First thing first we have to create default API response for test basic functionality and basic api result structure.

Create new directory under app/controller/ named api and then create a file named 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);
  }
}
            

To test the functionality, just open http://localhost/seme_framework/api/.

Create the model

We have to create the model for communicating between PHP Server and Database server.

Create new directory under model named api, and then create a file named a_apikey_model.php.

In the model we have to add some method such as insert, update, delete, get by id, get all data.

<?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();
  }
}
            

Create the controller for apikey

After create model, now we have to create controller for CRUD.

<?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);
  }
}
            

Test the API

After Completed the code, we can test the code by using Postman or create own test runner.

Seme Framework has supported for creating own test runner for testing the API.

Test apikey List

To test apikey list, you can open url directly in your browser to http://localhost/seme_framework/api/apikey/.

But, for another another function you have to tested it by using runner.

Here is some example for testing API through Postman.

Create

The test result for create data

Edit

The test result for edit data

Delete

The test result for delete data

Well done, if you facing any problem do not hestitate to open the issue on our github page.