API Controllers

Plugin REST API controllers live in the Api/ directory. They return JSON responses and follow the api/{plugin-slug}/v1/ URL prefix convention.

Location and Namespace

plugins/MyPlugin/Api/V1Controller.php
namespace: PluginsMyPluginApi

Controller Example

<?php

namespace PluginsMyPluginApi;

use AppControllersBaseController;
use CodeIgniterHTTPResponseInterface;

class V1Controller extends BaseController
{
    public function index(): ResponseInterface
    {
        $items = model('PluginsMyPluginModelsItemModel')
            ->where('status', 'published')
            ->findAll();

        return $this->response->setJSON([
            'success' => true,
            'data'    => $items,
            'count'   => count($items),
        ]);
    }

    public function show(int $id): ResponseInterface
    {
        $item = model('PluginsMyPluginModelsItemModel')->find($id);

        if ($item === null) {
            return $this->response
                ->setStatusCode(404)
                ->setJSON(['success' => false, 'message' => 'Not found']);
        }

        return $this->response->setJSON(['success' => true, 'data' => $item]);
    }

    public function create(): ResponseInterface
    {
        if (! $this->validate(['title' => 'required|min_length[3]'])) {
            return $this->response->setStatusCode(422)
                ->setJSON(['success' => false, 'errors' => $this->validator->getErrors()]);
        }
        // ... create logic
        return $this->response->setStatusCode(201)->setJSON(['success' => true, 'id' => $id]);
    }
}

Route Definitions

$routes->group('api/myplugin/v1', function ($routes) {
    $routes->get(   'items',        'PluginsMyPluginApiV1Controller::index');
    $routes->get(   'items/(:num)', 'PluginsMyPluginApiV1Controller::show/$1');
    $routes->post(  'items',        'PluginsMyPluginApiV1Controller::create');
    $routes->put(   'items/(:num)', 'PluginsMyPluginApiV1Controller::update/$1');
    $routes->delete('items/(:num)', 'PluginsMyPluginApiV1Controller::destroy/$1');
});

Response Envelope

{ "success": true, "data": { ... } }

{ "success": false, "message": "Error description", "errors": { "field": "msg" } }

HTTP Status Codes

StatusUsage
200Successful GET, PUT, DELETE
201Successful POST creating a resource
422Validation failed
404Resource not found
401Authentication required
403Authenticated but not authorized

Authentication Options

  • Session auth: auth()->user() available if user is logged in (global session filter)
  • Shield API tokens: add ['filter' => 'auth:tokens'] to route group; clients send Authorization: Bearer {token}
  • No auth: for public-read endpoints