0

I am having problems setting up an RESTful API with Kohana 3.3. I have added the following module (branch 3.3/release/v2.0), https://github.com/michal-m/kohana-modules-restful, to my bootstrap.

Kohana::modules(array(
    'restful' => MODPATH.'restful'
));

I've created a new controller, Controller_Api which extends RESTful_Controller and has get, update, create, delete actions. In my routes file I have:

Route::set('api', '(<controller>(/<action>(/<id>)))')
    ->defaults(array(
        'controller' => 'api',
        'action'     => 'index'
));

But the problem I'm having is when I go to: http://example.com/api/user/1

I get the following error which indicates my route is wrong but I can't work it out:

Kohana_HTTP_Exception [ 404 ]: Unable to find a route to match the URI: api/user/1

xylar
  • 7,433
  • 17
  • 55
  • 100
  • I'm the module creator. Can you just confirm which branch you're using, is it the `master` one? – Michal M Apr 25 '13 at 07:01
  • @MichalM I'm using `3.3/release/v2.0` – xylar Apr 25 '13 at 08:22
  • I found a bug in the module that might cause this issue on case-sensitive filesystems. Working on a fix. Will let you know when it's fixed. – Michal M Apr 25 '13 at 17:14
  • Actually, in your case it's a missing route filter that is required to map request method to action. Look into `restful/classes/RESTful/Core.php::route_filter()` method to see what needs to be done. – Michal M Apr 25 '13 at 17:17

3 Answers3

2

Firstly, get the latest 3.3/release/2.0 version. It's not final yet, but I've just pushed 2 important hotfixes.

Secondly, you have to add a route filter to translate request method (GET, POST, etc.) to appropriate actions. You can use one supplied with the module, like this:

Route::set('api', '(<controller>(/<action>(/<id>)))')
    ->filter('RESTful::route_filter')
    ->defaults(array(
        'controller' => 'api',
        'action'     => 'index'
));

Or create a simple one yourself, e.g.:

Route::set('api', '(<controller>(/<action>(/<id>)))')
    ->filter(function($route, $params, $request){
        $params['action'] = strtolower($request->method());
        return $params;
    })
    ->defaults(array(
        'controller' => 'api',
        'action'     => 'index'
));
Michal M
  • 9,322
  • 8
  • 47
  • 63
0
  1. Was restful module added successfully? You can try, for example, Kohana::autoload('RESTful_Controller') (returns boolean).
  2. Checkout your route list. Common mistake is to add your custom route after default catch-all route. Call Route::all() and you will see all routes in order they were added.
  3. Your route looks correct, but you can test it:
      $route = Route::get('api');
      $request = Request::factory('api/user/1');
      // since 3.3 Route::matches requires Request object
      $params = $route->matches($request);

$params should contain Request param names (controller, action etc). If your route is incorrect, $params is FALSE.

biakaveron
  • 5,493
  • 1
  • 16
  • 20
0

I'm use route filter. Route filters added in 3.3 version. Example:

bootstrap.php

Route::set('users', '(<controller>(/<id>))')
->filter(function ($route, $params, $request) {
    $params['action'] = strtolower($request->method()) . '_' . $params['action'];
    return $params;
})
->defaults(array('controller' => 'Users', 'action' => 'user'));

bootstrap.php (If need check authentication)

Route::set('users', '(<controller>(/<id>))')
->filter(function ($route, $params, $request) {
    if (Auth::instance()->logged_in())
    {
        $params['action'] = strtolower($request->method()) . '_' . $params['action'];
    }
    else
    {
        $params['action'] = 'noauth';
    }

    return $params;
})
->defaults(array('controller' => 'Users', 'action' => 'user'));

And code cuts from my controller.

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Users extends Controller {

    public function action_get_user ()
    {
       // GET method
    }

    public function action_post_user ()
    {
       // POST method
    }

    public function action_put_user ()
    {
       // PUT method
    }

    public function action_delete_user ()
    {
       // DELETE method
    }

    public function action_noauth ()
    {
       // No authentication response
    }
}
David
  • 3,392
  • 3
  • 36
  • 47