The problem you are facing isn't the casing of the action (in PHP method names are case insensitive), but the casing of the controller. It won't find APIController
and therefore throw an missing controller exception. Your AppController
is then being invoked as it is being extended by CakeErrorController
which is used on errors.
I can only assume that $this->Api
refers to a model, and since the actual controller is CakeErrorController
, that model of course isn't being loaded, hence the non-object error.
There are various ways to solve this problem, personally I'd probably hook in to the Dispatcher.beforeDispatch
event and throw an exception or define an appropriate response if necessary, something like this:
// app/Config/bootstrap.php
App::uses('CakeEvent', 'Event');
App::uses('CakeEventManager', 'Event');
CakeEventManager::instance()->attach(
function(CakeEvent $event) {
$controller = $event->data['request']->params['controller'];
$action = $event->data['request']->params['action'];
if(strtolower($controller) === 'api') {
$response = $event->data['response'];
if($controller !== 'api') {
$response->statusCode('403');
$response->body('Invalid controller message');
return $response;
}
if(strtolower($action) !== $action) {
$response->statusCode('403');
$response->body('Invalid action method');
return $response;
}
}
},
'Dispatcher.beforeDispatch',
array('priority' => 11)
);
This would enforce using lowercase for the controller and the action in case the api
controller is being targeted.
However as already mentioned, method names are case insensitive, so forcing lowercase for actions isn't necessary from a technical point of view. Anyways, it's just an example...