Welcome to Abdul Malik Ikhsan's Blog

Create API Service in CodeIgniter 4 with Request Filtering

Posted in CodeIgniter 4, Teknologi, Tutorial PHP by samsonasik on September 22, 2018

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 Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: