سؤال

Working on building an API and would like to use RESTful routes.

I got it to work just fine like this:

http://www.mysite.com/events.json  // returns json results with my events
http://www.mysite.com/events/123.json // returns json results with event of id '123'

BUT - I want to be able to do this using an 'api' prefix.

So, I added the api Routing prefix:

Configure::write('Routing.prefixes', array('admin', 'api'));

And changed my actions from 'view' and 'index' to 'api_view' and 'api_index'.

But now it doesn't work. (eg. I have to write the action name or it won't find the correct one based on HTTP.

The end goal would be to be able to do something like this:

GET http://www.mysite.com/api/1.0/events.json // loads events/api_index()
GET http://www.mysite.com/api/1.0/events/123.json // loads events/api_view($id)
DELETE http://www.mysite.com/api/1.0/events/123.json // loads events/api_delete($id)
...etc
هل كانت مفيدة؟

المحلول

I ended up having to just write the routes manually:

Router::parseExtensions('json', 'xml');

Router::connect('/api/:version/:controller/:id/*',
array('[method]'=>'GET', 'prefix'=>'api', 'action'=>'view'),
array('version'=>'[0-9]+\.[0-9]+', 'id'=>'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'));

Router::connect('/api/:version/:controller/*',
array('[method]'=>'GET', 'prefix'=>'api', 'action'=>'index'),
array('version'=>'[0-9]+\.[0-9]+'));

Router::connect('/api/*', array('controller'=>'events', 'action'=>'index', 'ext'=>'html'));

Notes:

The [method] is what forces the HTTP type (eg. RESTful)

The parseExtensions() makes it so you can have it display the data in different formats automatically by changing the extension in your URL.

The last Router:: line was just a catchall for anything /api/ that didn't match - it forwarded it to the homepage. Eventually I'll probably just route this to an API error page.

The 'ext'=>'html' of the last Router:: line was to keep parseExtensions from trying to use whatever extension was in the URL - if it's redirecting for reasons they made the call wrong, I just want it to go back to the homepage (or whatever) and use the normal view.

نصائح أخرى

Try something like this.

Router::connect('/:api/:apiVersion/:controller/:action/*',
    array(),
    array(
        'api' => 'api',
        'apiVersion' => '1.0|1.1|'
    )
);

With prefix routing

Router::connect('/:prefix/:apiVersion/:controller/:action/*',
    array(),
    array(
        'prefix' => 'api',
        'apiVersion' => '1.0|1.1|'
    )
);

Will match only valid API versions like 1.0 and 1.1 here. If you want something else use a regex there.

I know this is an old post, but there is a routing method called mapResources which creates the special method based routing for you.

http://book.cakephp.org/2.0/en/development/rest.html

You put it in routes.php like so:

Router::mapResources(array('controller1', 'controller2'));

The docs have a nice little table showing how the requests are mapped to different actions, which you can always override if you need to.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top