如何在Cakephp中的RESTful api中的URL中给出字符串?

时间:2013-06-14 12:03:26

标签: php web-services rest cakephp cakephp-2.1

根据这个Cakephp CookBook RESTful api的简单设置:

HTTP Method     URL.method  Controller action invoked
GET     /recipes*.method*   RecipesController::index()
GET     /recipes/123.method     RecipesController::view(123)
POST    /recipes*.method*   RecipesController::add()
PUT     /recipes/123*.method*   RecipesController::edit(123)
DELETE  /recipes/123.method     RecipesController::delete(123)
POST    /recipes/123*.method*   RecipesController::edit(123)

这里所有的URL参数都是数字,即123。 当我尝试使用字符串,即

GET     /recipes/test.json  RecipesController::view(123)

这给了我一个错误:

{
   code: "404"
   url: "/myproject/recipes/test.json"
   name: "Action RecipesController::test() could not be found."
}

此处为网址

     "/myproject/recipes/test.json" // doesn't work

but 
      "/myproject/recipes/123.json" // works 

我使用默认的Router::mapResources('recipes')

提前致谢!

2 个答案:

答案 0 :(得分:6)

好吧,为这段代码阅读the API,点之前传递的值会自动与idUUID匹配。在那个API中就是params定义

  

' ID' - 匹配ID时使用的正则表达式片段。通过   default,匹配整数值和UUID。

mapResources所做的只是添加了大量Router::connect一些预先建立的选项(基本上具有:controller /:action /:id 的形式) 。

因此,如果规则是将id(蛋糕认为是整数)与正则表达式匹配,那么显然你的字符串没有通过验证。因此,Router跳过connect规则并转到另一个,直到一个匹配。匹配的那个是:controller /:action.extension (可能)的形式。这就是您收到错误的原因,test显然不是一个行动。

幸运的是,mapResources为自定义提供的选项之一是匹配$id的规则。

将字符串选项添加为" ids" (因为如果你使用mapResources添加连接路由,这是REST动作将要接收的唯一变量),更改验证该规则的正则表达式

Router::mapResources('recipes', array('id'=>'[0-9A-Za-z]'));

或者你想制作的任何规则(我对正则表达式不好,所以尽量根据你的需要调整它)。

查看API的the docs,了解您可以添加的其他选项。

请记住,mapResources可以让您的生活更轻松,所以如果您需要更复杂的路线以及更多的参数或额外的东西,请考虑忘记mapResources并自行构建路线(就像它一样)在您提供的链接页面底部说。)

答案 1 :(得分:1)

在代码中定义您的路线:

// used for the rest API 
$routes->extensions(['json','xml']); // type of format you want to get response
$routes->resources('Api');

然后在控制器文件夹

内为API创建一个控制器
<?php
namespace App\Controller;
use Cake\I18n\Time;
use Cake\Database\Type; 
Type::build('date')->setLocaleFormat('yyyy-MM-dd'); // customize date format

// src/Controller/RecipesController.php
class ApiController extends AppController
{

    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('RequestHandler');
        // load Model 
        $this->loadModel('Sales'); // load model to fetch data from database
        $this->Auth->allow();      // allow URL to public in case of Auth check 
    }

    public function beforeFilter(\Cake\Event\Event $event)
    {
        parent::beforeFilter($event);
        $this->loadComponent('RequestHandler');     
        $this->loadComponent('Flash');

    }

    public function index($fromdate = null, $todate = null)
    {
        //set date range to fetch the sales in particular date 
        if(!empty($_GET['fromdate_utc']) && !empty($_GET['todate_utc'])){
            // if from amd to date are same add +1 day in to date to get result 
            $to_date = date('Y-m-d', strtotime($_GET['todate_utc'] . ' +1 day'));
            $dateRage = array('Sales.SalesDate >= ' => $_GET['fromdate_utc'], 'Sales.SalesDate <=' => $to_date);
        }else{
            $dateRage = array();                    
        }

        $conditions = array(
            'and' => array($dateRage),
        );

        //$this->Auth->allow();
        $sales= $this->Sales->find('all', array(
                        'conditions' => $conditions
                    ))
                    ->select(['SalesNo', 'SalesDate', 'TotalValue', 'TotalDiscount', 'NetTotal', 'PaymentMode', 'Status'])
                    ->where(['StoreId' => '1']);
       // set data for view or response of API
        $this->set([
            'sales' => $sales,
            '_serialize' => ['sales']
        ]);
    }

}

?>

如何在API URL中传递参数以进行XML格式检查: -

https://example.com/api/index.xml?fromdate_utc=2016-10-03&todate_utc=2016-10-03

如何在API URL中传递参数以进行JSON格式检查: -

https://example.com/api/index.json?fromdate_utc=2016-10-03&todate_utc=2016-10-03