, (*1)
CodeIgniter RESTful API
CodeIgniter 3 RESTful API Resource Base Controller, (*2)
, (*3)
This RESTful API extension is collected into yidas/codeigniter-pack which is a complete solution for Codeigniter framework., (*4)
Features
-
PSR-7 standardization, (*5)
-
RESTful API implementation, (*6)
-
Laravel Resource Controllers pattern like, (*7)
OUTLINE
DEMONSTRATION
class ApiController extends yidas\rest\Controller
{
public function index()
{
return $this->response->json(['bar'=>'foo']);
}
}
Output with status 200 OK
:, (*8)
{"bar":"foo"}
RESTful Create Callback
public function store($requestData=null) {
$this->db->insert('mytable', $requestData);
$id = $this->db->insert_id();
return $this->response->json(['id'=>$id], 201);
}
Output with status 201 Created
:, (*9)
{"id":1}
try {
throw new Exception("API forbidden", 403);
} catch (\Exception $e) {
// Pack data into a standard format
$data = $this->pack(['bar'=>'foo'], $e->getCode(), $e->getMessage());
return $this->response->json($data, $e->getCode());
}
Output with status 403 Forbidden
:, (*10)
{"code":403,"message":"API forbidden","data":{"bar":"foo"}}
REQUIREMENTS
This library requires the following:, (*11)
- PHP 5.4.0+
- CodeIgniter 3.0.0+
INSTALLATION
Run Composer in your Codeigniter project under the folder \application
:, (*12)
composer require yidas/codeigniter-rest
Check Codeigniter application/config/config.php
:, (*13)
$config['composer_autoload'] = TRUE;
You could customize the vendor path into $config['composer_autoload']
, (*14)
CONFIGURATION
- Create a controller to extend
yidas\rest\Controller
,
class Resource extends yidas\rest\Controller {}
- Add and implement action methods referring by Build Methods.
Then you could access RESTful API:, (*15)
https://yourname.com/resource/api
https://yourname.com/resource/api/123
You could also use /ajax
instead of /api
if you like:, (*16)
https://yourname.com/resource/ajax
https://yourname.com/resource/ajax/123
resource
is Controller name, if you don't want to have /api
or /ajax
in URI you could set Routes Setting as below., (*17)
Routes Setting
If you want to have a standard RESTful URI pattern that controller defines as a URI resource, for example:, (*18)
https://yourname.com/resource
https://yourname.com/resource/123
You could add a pair of routes for this controller into \application\config\routes.php
to enable RESTful API url:, (*19)
$route['resource_name'] = '[Controller]/route';
$route['resource_name/(:any)'] = '[Controller]/route/$1';
RESOURCE CONTROLLERS
The base RESTful API controller is yidas\rest\Controller
, the following table is the actions handled by resource controller, the action
refers to CI_Controller
's action name which you could override:, (*20)
HTTP Method |
URI (Routes Setting) |
Action |
Description |
GET |
/photos |
index |
List the collection's members. |
POST |
/photos |
store |
Create a new entry in the collection. |
GET |
/photos/{photo} |
show |
Retrieve an addressed member of the collection. |
PUT/PATCH |
/photos/{photo} |
update |
Update the addressed member of the collection. |
PUT |
/photos |
update |
Update the entire collection. |
DELETE |
/photos/{photo} |
delete |
Delete the addressed member of the collection. |
DELETE |
/photos |
delete |
Delete the entire collection. |
Without Routes Setting, the URI is like /photos/api
& /photos/api/{photo}
., (*21)
Build Methods:
You could make a resource controller by referring the Template of Resource Controller., (*22)
The following RESTful controller methods could be add by your need. which each method refers to the action of Resource Controller table by default, and injects required arguments:, (*23)
public function index() {}
protected function store($requestData=null) {}
protected function show($resourceID) {}
protected function update($resourceID=null, $requestData=null) {}
protected function delete($resourceID=null, $requestData=null) {}
$resourceID
(string) is the addressed identity of the resource from request, (*24)
$requestData
(array) is the array input data parsed from request raw body, which supports data format of common content types. (Alternatively, use this->request->getRawBody()
to get raw data), (*25)
Custom Routes & Methods
The default routes for mapping the same action methods of Resource Controller are below:, (*26)
protected $routes = [
'index' => 'index',
'store' => 'store',
'show' => 'show',
'update' => 'update',
'delete' => 'delete',
];
You could override it to define your own routes while creating a resource controller:, (*27)
class ApiController extends yidas\rest\Controller {
protected $routes = [
'index' => 'find',
'store' => 'save',
'show' => 'display',
'update' => 'edit',
'delete' => 'destory',
];
}
After reseting routes, each RESTful method (key) would enter into specified controller action (value). For above example, while access /resources/api/
url with GET
method would enter into find()
action. However, the default route would enter into index()
action., (*28)
The keys refer to the actions of Resource Controller table, you must define all methods you need., (*29)
Behaviors
Resource Controller supports behaviors setting for each action, you could implement such as authentication for different permissions., (*30)
_setBehavior()
Set behavior to a action before route, (*31)
protected boolean _setBehavior(string $action, callable $function)
Example:, (*32)
class BaseRestController extends \yidas\rest\Controller
{
function __construct()
{
parent::__construct();
// Load your Auth library for verification
$this->load->library('Auth');
$this->auth->verify('read');
// Set each action for own permission verification
$this->_setBehavior('store', function() {
$this->auth->verify('create');
});
$this->_setBehavior('update', function() {
$this->auth->verify('update');
});
$this->_setBehavior('delete', function() {
$this->auth->verify('delete');
});
}
// ...
Usage
pack()
Pack array data into body format, (*33)
You could override this method for your application standard., (*34)
protected array pack(array|mixed $data, integer $statusCode=200, string $message=null)
````
*Example:*
```php
$data = $this->pack(['bar'=>'foo'], 403, 'Forbidden');
return $this->response->json($data, 403);
JSON Result:, (*35)
{
"code": 403,
"message": "Forbidden",
"data": {
"bar": "foo"
}
}
HTTP REQUEST
The PSR-7 request component yidas\http\request
is preloaded into yidas\rest\Controller
, which provides input handler and HTTP Authentication. You could call it by $this->request
in controller class., (*36)
Usage
getRawBody()
Returns the raw HTTP request body, (*37)
public string getRawBody()
Example:, (*38)
// Request with `application/json` raw
$data = json_decode($this->request->getRawBody);
getAuthCredentialsWithBasic()
Get Credentials with HTTP Basic Authentication, (*39)
public array getAuthCredentialsWithBasic()
Example:, (*40)
list($username, $password) = $this->request->getAuthCredentialsWithBasic();
getAuthCredentialsWithBearer()
Get Credentials with OAuth 2.0 Authorization Framework: Bearer Token Usage, (*41)
public string getAuthCredentialsWithBearer()
Example:, (*42)
$b64token = $this->request->getAuthCredentialsWithBearer();
HTTP RESPONSE
The PSR-7 response component yidas\http\response
is preloaded into yidas\rest\Controller
, which provides output handler and formatter. You could call it by $this->response
in controller class., (*43)
Usage
json()
JSON output shortcut, (*44)
public void json(array|mixed $data, integer $statusCode=null)
Example:, (*45)
$this->response->json(['bar'=>'foo'], 201);
Set Response Format into CI_Output, (*46)
public self setFormat(string $format)
Example:, (*47)
$this->response->setFormat(\yidas\http\Response::FORMAT_JSON);
setData()
Set Response Data into CI_Output, (*48)
public self setData(mixed $data)
Example:, (*49)
$this->response->setData(['foo'=>'bar']);
send()
Sends the response to the client., (*50)
public void send()
Example:, (*51)
$this->response->send();
Return an instance with the specified header appended with the given value., (*52)
public self withAddedHeader(string $name, string $value)
Example:, (*53)
return $this->response
->withAddedHeader('Access-Control-Allow-Origin', '*')
->withAddedHeader('X-Frame-Options', 'deny')
->json(['bar'=>'foo']);
REFERENCE