TL;DR: use the components => urlManager => rules to use HTTP verbs and don’t forget to authenticate the request. Check out on github my sample project that provides a simple RESTFUL API.

Yii 1.x is not the best framework to write RESTFUL APIs. Its main problem it the lack of good handling of HTTP verbs other than POST and GET. However, PUT and DELETE become essential when one want to write a proper API. Fortunately, it is easy enough to add the missing support to Yii.

First, write a proper route configuration. Edit protected/config/main file and write something like this:

      'components'=>array(
          ...
          'urlManager'=>array(
              'urlFormat'=>'path',
              'rules'=>array(
                  '<controller:\w+>/<id:\d+>'=>'<controller>/view',
                  '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                  '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
                  array('api/index', 'pattern'=> 'api/', 'verb' => 'GET'),
                  array('api/create', 'pattern'=> 'api/','verb' => 'POST'),
                  array('api/update', 'pattern'=> 'api/','verb' => 'PUT'),
                  array('api/delete', 'pattern'=> 'api/','verb' => 'DELETE'),
              ),  
          ),  
          ...

the last four lines of the rules will instruct Yii that GET/POST/PUT/DELETE requests to BASEURL/api will be handled by the ApiController class within the functions actionIndex, actionCreate, actionUpdate, actionDelete respectively.

Then, it is necessary to write some basic code for handling the API calls. We must at least 1) get the data and 2) authenticate the requests. Moreover, we may also want to log calls and so on. We will do all this in the beforeAction funcion of ApiController.

To get data from the request we must take into account the type of the request. In the case of a GET, data will be into the $\_GET variable. The POST can be either a form request either a raw data request (typically a JSON one). In the first case its data will be in the $\_POST variable, while in the second case we must fetch data from PHP raw input stream which can be accessed via php://input. The PUT and the DELETE only have raw input.

In order to get data from raw input stream, we can write a very simple data function like:

    private function getContent()
    {
        if (null === $this->content)
        {
            if (0 === strlen(($this->content = file_get_contents('php://input'))))
            {
                $this->content = false;
            }
        }

        return $this->content;
    }

Next, we can use such a function to get data according to the request type:

        switch($_SERVER['REQUEST_METHOD']) {
        case 'GET':
            $this->data = $_GET;
            break;
        case 'POST':
            $this->data = CJSON::decode($this->getContent());
            break;
        case 'DELETE':
            $this->data = CJSON::decode($this->getContent());
            break;
        case 'PUT':
            $this->data = CJSON::decode($this->getContent());
            break;
        default:
            // raise some error here
            break;
        }

Here, I talk about authentication.