Quantcast
Channel: Live News for Yii Framework
Viewing all articles
Browse latest Browse all 2941

[Wiki] Building a REST API in Yii 2.0

$
0
0

This wiki article shows a simple REST API built with Yii 2.0. Example is based on the following table:

CREATE TABLE user (
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(255),
  age INT,
  createdAt DATETIME,
  updatedAt DATETIME
)

1. index action

Request

GET api/user/index

{
    "page":1,
    "limit":5,
    "sort":"id",
    "order":false,
    "filter":{}
}
  • page is the current page number.
  • limit is the number of records per page.
  • sort is the name of the field used for sorting i.e. it can be id, name, age, createdAt or updatedAt.
  • order can be either true or false. true means ascending while false means descending.
  • filter is json object to pass any filter elements. e.g. {name:'abc', age:20}.

Response

{
    "status": 1,
    "data": [
        {
            "id": 30,
            "name": "john",
            "age": 78,
            "createdAt": "2014-09-05 01:53:31",
            "updatedAt": "2014-09-05 01:53:51"
        },
        {
            "id": 29,
            "name": "ben",
            "age": 23,
            "createdAt": "2014-09-05 01:53:28",
            "updatedAt": "2014-09-05 01:54:00"
        },
        {
            "id": 28,
            "name": "rahul",
            "age": 72,
            "createdAt": "2014-09-05 01:53:25",
            "updatedAt": "2014-09-05 01:54:09"
        },
        {
            "id": 27,
            "name": "shafeeque",
            "age": 76,
            "createdAt": "2014-09-05 01:53:21",
            "updatedAt": "2014-09-05 01:54:24"
        },
        {
            "id": 26,
            "name": "sirin",
            "age": 73,
            "createdAt": "2014-09-04 19:51:49",
            "updatedAt": "2014-09-05 01:54:32"
        }
    ],
    "totalItems": "8"
}

Action Source code

public function actionIndex()
{
    $params = $_REQUEST;
    $filter = [];
 
    $page = 1;  /* default page number */
    $limit = 10; /* default limit */
 
 
    if (isset($params['page'])) {
        $page = $params['page'];
    }
 
    if (isset($params['limit'])) {
        $limit = $params['limit'];
    }
 
    $offset = $limit * ($page - 1);
 
 
    /* Filter elements */
    if (isset($params['filter'])) {
         $filter = (array)json_decode($params['filter']);
    }
 
    /* Sort field */
    $sort = "";
    if (isset($params['sort'])) {
        $sort = $params['sort'];
        if (isset($params['order'])) {  
            if ($params['order'] == "false") {
                $sort .= " desc";
            } else {
                $sort .= " asc";
            }
 
        }
    }
 
 
 
    $models = User::find()
        ->offset($offset)
        ->limit($limit)
        ->andFilterWhere(['like', 'id', $filter['id']])
        ->andFilterWhere(['like', 'name', $filter['name']])
        ->andFilterWhere(['like', 'age', $filter['age']])
        ->orderBy($sort)
        ->all();
 
    $totalItems = User::find()              
        ->andFilterWhere(['like', 'id', $filter['id']])
        ->andFilterWhere(['like', 'name', $filter['name']])
        ->andFilterWhere(['like', 'age', $filter['age']])
        ->count();    
 
    $data = [];
    foreach ($models as $m) {
        $data[] = array_filter($m->attributes);
    }     
 
    $this->setHeader(200);
 
    echo json_encode(['status' => 1, 'data' => $data, 'totalItems' => $totalItems], JSON_PRETTY_PRINT);
 
}
 
/* Functions to set header with status code. eg: 200 OK ,400 Bad Request etc..*/        
 
private function setHeader($status)
{     
    $status_header = 'HTTP/1.1 ' . $status . ' ' . $this->_getStatusCodeMessage($status);
    $content_type = "application/json; charset=utf-8";
 
    header($status_header);
    header('Content-type: ' . $content_type);
    header('X-Powered-By: ' . "Nintriva <nintriva.com>");
}
 
    private function _getStatusCodeMessage($status)
    {
          $codes = Array(
              200 => 'OK',
              400 => 'Bad Request',
              401 => 'Unauthorized',
              402 => 'Payment Required',
              403 => 'Forbidden',
              404 => 'Not Found',
              500 => 'Internal Server Error',
              501 => 'Not Implemented',
          );
          return (isset($codes[$status])) ? $codes[$status] : '';
          }

2.Action View

       Request:
           URL: api/user/view/30
    method:GET

       Note1: "30"=>is the Pk of a record in the user table

Response:

{
                "status": 1,
                "data": {
                    "id": 30,
                    "name": "john",
                    "age": 78,
                    "createdAt": "2014-09-05 01:53:31",
                    "updatedAt": "2014-09-05 01:53:51"
                }
              }

Action Source code:

public function actionView($id)
              {
 
                $model=$this->findModel($id);
 
                $this->setHeader(200);
                echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
 
              } 
               /* function to find the requested record/model */
                      protected function findModel($id)
              {
                  if (($model = User::findOne($id)) !== null) {
                  return $model;
                  } else {
 
                $this->setHeader(400);
                echo json_encode(array('status'=>0,'error_code'=>400,'message'=>'Bad request'),JSON_PRETTY_PRINT);
                exit;
                  }
              }

3.Action Create

       Request:

            URL:  api/user/create
     method:POST
params:
             {
              "name":"abc",
              "age":20,
            }

Response:

{
                  "status": 1,
                  "data": {
                  "id": 32,
                  "name": "abc",
                  "age": "20",
                  "createdAt": "2014-09-05 02:35:18",
                  "updatedAt": "2014-09-05 02:35:18"
                  }
             }

Action Source code:

public function actionCreate()
            {
 
                $params=$_REQUEST;
 
                $model = new User();
                $model->attributes=$params;
 
 
                if ($model->save()) {
 
                $this->setHeader(200);
                echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
 
                } 
                else
                {
                $this->setHeader(400);
                echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
                }
 
            }

4.Action Update

       Request:

            URL: api/user/update/32


            Note1:"32"=>id(PK) of the record we are going to update


     method: POST

params:

params:
           {
              "name":"efg",
              "age":25,
            }

Response:

{
                  "status": 1,
                  "data": {
                  "id": 32,
                  "name": "efg",
                  "age": "25",
                  "createdAt": "2014-09-05 02:35:18",
                  "updatedAt": "2014-09-05 02:45:55"
                  }
             }

Action Source code:

public function actionUpdate($id)
            {
                $params=$_REQUEST;
 
                $model = $this->findModel($id);
 
                $model->attributes=$params;
 
                if ($model->save()) {
 
                $this->setHeader(200);
                echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
 
                } 
                else
                {
                $this->setHeader(400);
                echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
                }
 
            }

5.Action Delete

       Request:

            URL: api/user/update/32
         method:DELETE 

            Note1:"32"=>id(PK) of the record we are going to delete
Response:
                {
                  "status": 1,
                  "data": {
                  "id": 32,
                  "name": "efg",
                  "age": 20,
                  "createdAt": "2014-09-05 02:40:44",
                  "updatedAt": "2014-09-05 02:40:44"
                  }
              }

Action Source code:

public function actionDelete($id)
              {
                  $model=$this->findModel($id);
 
                  if($model->delete())
                  { 
                  $this->setHeader(200);
                  echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
 
                  }
                  else
                  {
 
                  $this->setHeader(400);
                  echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
                  }
 
              }

6.Action DeleteAll

Used to delete multiple records at a time.

       Request:

            URL: api/user/deleteall
         method:POST

params:

{
                       "ids":"[27,28]"
                     }
            Note1:"ids"=>a list of id(Pk)'s to be deleted

Response:

{
                "status": 1,
                "data": [
                {
                    "id": 27,
                    "name": "shafeeque",
                    "age": 76,
                    "createdAt": "2014-09-05 01:53:21",
                    "updatedAt": "2014-09-05 01:54:24"
                },
                {
                    "id": 28,
                    "name": "rahul",
                    "age": 72,
                    "createdAt": "2014-09-05 01:53:25",
                    "updatedAt": "2014-09-05 01:54:09"
                }
                ]
            }

Action Source code:

public function actionDeleteall()
              {
                  $ids=json_decode($_REQUEST['ids']);
 
                  $data=array();
 
                  foreach($ids as $id)
                  {
                $model=$this->findModel($id);
 
                if($model->delete())
                  $data[]=array_filter($model->attributes);
                else
                {
                  $this->setHeader(400);
                  echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
                  return;
                }  
                  }
 
                  $this->setHeader(200);
                  echo json_encode(array('status'=>1,'data'=>$data),JSON_PRETTY_PRINT);
 
              }

7.Behaviour to fileter action methods

public function behaviors()
                  {
                  return [
                      'verbs' => [
                      'class' => VerbFilter::className(),
                      'actions' => [
                          'index'=>['get'],
                          'view'=>['get'],
                          'create'=>['post'],
                          'update'=>['post'],
                          'delete' => ['delete'],
                          'deleteall'=>['post'],
                      ],
 
                      ]
                  ];
                  }
 
                   /* This will execute before  any action */
                  public function beforeAction($event)
                  {
                  $action = $event->id;
                  if (isset($this->actions[$action])) {
                      $verbs = $this->actions[$action];
                  } elseif (isset($this->actions['*'])) {
                      $verbs = $this->actions['*'];
                  } else {
                      return $event->isValid;
                  }
                  $verb = Yii::$app->getRequest()->getMethod();
 
                $allowed = array_map('strtoupper', $verbs);
 
                if (!in_array($verb, $allowed)) {
 
                      $this->setHeader(400);
                      echo json_encode(array('status'=>0,'error_code'=>400,'message'=>'Method not allowed'),JSON_PRETTY_PRINT);
                      exit;
 
                  }  
 
                return true;  
                  }

Controller source code:UserController.php

namespace app\modules\api\controllers;
 
        use Yii;
        use app\models\User;
        use yii\data\ActiveDataProvider;
        use yii\web\Controller;
        use yii\web\NotFoundHttpException;
        use yii\filters\VerbFilter;
 
        /**
        * UserController implements the CRUD actions for User model.
        */
        class UserController extends Controller
        {
 
        public function behaviors()
        {
            return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                'index'=>['get'],
                'view'=>['get'],
                'create'=>['post'],
                'update'=>['post'],
                'delete' => ['delete'],
                'deleteall'=>['post'],
                ],
 
            ]
            ];
        }
 
 
        public function beforeAction($event)
        {
            $action = $event->id;
            if (isset($this->actions[$action])) {
            $verbs = $this->actions[$action];
            } elseif (isset($this->actions['*'])) {
            $verbs = $this->actions['*'];
            } else {
            return $event->isValid;
            }
            $verb = Yii::$app->getRequest()->getMethod();
 
          $allowed = array_map('strtoupper', $verbs);
 
          if (!in_array($verb, $allowed)) {
 
            $this->setHeader(400);
            echo json_encode(array('status'=>0,'error_code'=>400,'message'=>'Method not allowed'),JSON_PRETTY_PRINT);
            exit;
 
            }  
 
          return true;  
        }
 
        /**
        * Lists all User models.
        * @return mixed
        */
        public function actionIndex()
        {
 
              $params=$_REQUEST;
              $filter=array();
              $sort="";
 
              $page=1;
              $limit=10;
 
              if(isset($params['page']))
            $page=$params['page'];
 
 
              if(isset($params['limit']))
              $limit=$params['limit'];
 
            $offset=$limit*($page-1);
 
 
            /* Filter elements */
              if(isset($params['filter']))
            {
            $filter=(array)json_decode($params['filter']);
            }
 
 
 
            if(isset($params['sort']))
            {
              $sort=$params['sort'];
                if(isset($params['order']))
                {  
                if($params['order']=="false")
                $sort.=" desc";
                else
                $sort.=" asc";
 
                }
            }
 
 
 
                $models=User::find()
                    ->offset($offset)
                    ->limit($limit)
 
                    ->andFilterWhere(['like', 'id', $filter['id']])
                    ->andFilterWhere(['like', 'name', $filter['name']])
                    ->andFilterWhere(['like', 'age', $filter['age']])
 
 
                    ->orderBy($sort)
                    ->all();
 
 
                $totalItems=User::find()
                        ->andFilterWhere(['like', 'id', $filter['id']])
                        ->andFilterWhere(['like', 'name', $filter['name']])
                        ->andFilterWhere(['like', 'age', $filter['age']])
                        ->count();
 
 
 
              $data=array();
              foreach($models as $m)
              { 
            $data[]=array_filter($m->attributes);
              }     
 
              $this->setHeader(200);
 
              echo json_encode(array('status'=>1,'data'=>$data,'totalItems'=>$totalItems),JSON_PRETTY_PRINT);
 
        }
 
 
        /**
        * Displays a single User model.
        * @param integer $id
        * @return mixed
        */
        public function actionView($id)
        {
 
          $model=$this->findModel($id);
 
          $this->setHeader(200);
          echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
 
        }
 
        /**
        * Creates a new User model.
        * @return json
        */
        public function actionCreate()
        {
 
            $params=$_REQUEST;
 
            $model = new User();
            $model->attributes=$params;
 
 
 
            if ($model->save()) {
 
            $this->setHeader(200);
            echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
 
            } 
            else
            {
            $this->setHeader(400);
            echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
            }
 
        }
 
        /**
        * Updates an existing User model.
        * @param integer $id
        * @return json
        */
        public function actionUpdate($id)
        {
            $params=$_REQUEST;
 
            $model = $this->findModel($id);
 
            $model->attributes=$params;
 
            if ($model->save()) {
 
            $this->setHeader(200);
            echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
 
            } 
            else
            {
            $this->setHeader(400);
            echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
            }
 
        }
 
        /**
        * Deletes an existing User model.
        * @param integer $id
        * @return json
        */
        public function actionDelete($id)
        {
            $model=$this->findModel($id);
 
            if($model->delete())
            { 
            $this->setHeader(200);
            echo json_encode(array('status'=>1,'data'=>array_filter($model->attributes)),JSON_PRETTY_PRINT);
 
            }
            else
            {
 
            $this->setHeader(400);
            echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
            }
 
        }
        /**
        * Deletes an existing multiple User models at a time.
        * @return json
        */
        public function actionDeleteall()
        {
            $ids=json_decode($_REQUEST['ids']);
 
            $data=array();
 
            foreach($ids as $id)
            {
              $model=$this->findModel($id);
 
              if($model->delete())
            $data[]=array_filter($model->attributes);
              else
              {
            $this->setHeader(400);
            echo json_encode(array('status'=>0,'error_code'=>400,'errors'=>$model->errors),JSON_PRETTY_PRINT);
            return;
              }  
            }
 
            $this->setHeader(200);
            echo json_encode(array('status'=>1,'data'=>$data),JSON_PRETTY_PRINT);
 
        }
 
        /**
        * Finds the User model based on its primary key value.
        * If the model is not found, a 404 HTTP exception will be thrown.
        * @param integer $id
        * @return User the loaded model
        */
        protected function findModel($id)
        {
            if (($model = User::findOne($id)) !== null) {
            return $model;
            } else {
 
              $this->setHeader(400);
              echo json_encode(array('status'=>0,'error_code'=>400,'message'=>'Bad request'),JSON_PRETTY_PRINT);
              exit;
            }
        }
 
        private function setHeader($status)
          {
 
              $status_header = 'HTTP/1.1 ' . $status . ' ' . $this->_getStatusCodeMessage($status);
              $content_type="application/json; charset=utf-8";
 
              header($status_header);
              header('Content-type: ' . $content_type);
              header('X-Powered-By: ' . "Nintriva <nintriva.com>");
          }
        private function _getStatusCodeMessage($status)
        {
            // these could be stored in a .ini file and loaded
            // via parse_ini_file()... however, this will suffice
            // for an example
            $codes = Array(
            200 => 'OK',
            400 => 'Bad Request',
            401 => 'Unauthorized',
            402 => 'Payment Required',
            403 => 'Forbidden',
            404 => 'Not Found',
            500 => 'Internal Server Error',
            501 => 'Not Implemented',
            );
            return (isset($codes[$status])) ? $codes[$status] : '';
        }
        }

Happy coding..

Sirin

Nintriva

www.nintriva.com


Viewing all articles
Browse latest Browse all 2941

Trending Articles