Create API Service in CodeIgniter 4 with Request Filtering
In CodeIgniter 4, there is a trait that specialized to be used for API, named CodeIgniter\API\ResponseTrait
for that, that consist of collection of functionality to build a response. How about request filtering ? We will need a filter class that implements CodeIgniter\Filters\FilterInterface
interface.
For example, we are going to create a /api/ping
api service, which will returns time value, we can create controller as follow:
<?php // application/Controllers/Api/Ping.php declare(strict_types=1); namespace App\Controllers\Api; use function time; use CodeIgniter\API\ResponseTrait; use CodeIgniter\Controller; use CodeIgniter\HTTP\ResponseInterface; final class Ping extends Controller { use ResponseTrait; public function index(): ResponseInterface { return $this->respond(['ack' => time()]); } }
Without filtering, we can call url and got result like the following based on Accept header, for example, for application/xml
, it will get:
➜ ~ curl -i -H "Accept: application/xml" http://localhost:8080/api/ping HTTP/1.1 200 OK Host: localhost:8080 Date: Sat, 22 Sep 2018 01:11:30 -0500 Connection: close X-Powered-By: PHP/7.2.9 Cache-control: no-store, max-age=0, no-cache Content-Type: application/xml; charset=UTF-8 Debugbar-Time: 1537596690 Debugbar-Link: http://localhost:8080/index.php/?debugbar_time=1537596690 <?xml version="1.0"?> <response><ack>1537596690</ack></response>
and when it changed to application/json
, it will get:
➜ ~ curl -i -H "Accept: application/json" http://localhost:8080/api/ping HTTP/1.1 200 OK Host: localhost:8080 Date: Sat, 22 Sep 2018 01:11:53 -0500 Connection: close X-Powered-By: PHP/7.2.9 Cache-control: no-store, max-age=0, no-cache Content-Type: application/json; charset=UTF-8 Debugbar-Time: 1537596713 Debugbar-Link: http://localhost:8080/index.php/?debugbar_time=1537596713 { "ack": 1537596713 }
Let’s try create filter it to only allow the “POST” request! We can create filter as follow:
<?php // application/Filters/PostRequestOnly.php declare(strict_types=1); namespace App\Filters; use CodeIgniter\Filters\FilterInterface; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use Config\Services; final class PostRequestOnly implements FilterInterface { public function before(RequestInterface $request) { if ($request->getMethod() === 'post') { return; } return Services::response() ->setStatusCode(ResponseInterface::HTTP_METHOD_NOT_ALLOWED); } public function after(RequestInterface $request, ResponseInterface $response) { } }
In above PostRequestOnly
filter, we are allowing request only for “POST”, other request methods will get response with “Method Not Allowed” (405). To make it work, we need register it into Config\Filters
::$aliases
class under application
directory, and ensure it applied into Config\Filters
::$filters
to register specific uri for the filter, as follow:
<?php // application/Config/Filters.php // ... use App\Filters\PostRequestOnly; class Filters extends BaseConfig { public $aliases = [ // ... 'postRequestOnly' => PostRequestOnly::class, ]; // ... public $filters = [ // ... 'postRequestOnly' => [ 'before' => [ 'api/ping', ], ], ]; }
That’s it! Now, when we try to see different result with GET
and POST
, it will get the following response:
GET: Method Not Allowed 405
➜ ~ curl -i -H "Accept: application/json" -X GET http://localhost:8080/api/ping HTTP/1.1 405 Method Not Allowed Host: localhost:8080 Date: Sat, 22 Sep 2018 13:12:22 +0700 Connection: close X-Powered-By: PHP/7.2.9 Cache-control: no-store, max-age=0, no-cache Content-Type: text/html; charset=UTF-8
POST: Got Response OK 200
➜ ~ curl -i -H "Accept: application/json" -X POST http://localhost:8080/api/ping HTTP/1.1 200 OK Host: localhost:8080 Date: Sat, 22 Sep 2018 01:12:54 -0500 Connection: close X-Powered-By: PHP/7.2.9 Cache-control: no-store, max-age=0, no-cache Content-Type: application/json; charset=UTF-8 Debugbar-Time: 1537596774 Debugbar-Link: http://localhost:8080/index.php/?debugbar_time=1537596774 { "ack": 1537596774 }
leave a comment