Problemi Con Path Rules

Sono un po’ di coccio con i path.

Sto cercando di fare una rule per avere api/<controller> che mi richiami <controller>Json/index.

Quindi se vado nel link /api/order dovrei chiamare l’action index del controller OrderJson.

Bene, io ho scritto questo:




'urlManager'=>array(

    'urlFormat'=>'path', 

    'showScriptName'=>false, //elimino index.php dall'url, richiede .htaccess configurato

    'rules'=>array(

        '<controller:\w+>/<id:\d+>'=>'<controller>/view',

        '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',

        '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',

        // REST patterns

        'api/<controller:\w+>' => array('<controller>Json/index', 'verb'=>'GET'),

    ),

),



In questo modo però mi ritorna sempre Unable to resolve the request "api/order".

Ho notato che se metto qualcosa dopo il controller, ad esempio:


'api/<controller:\w+>/index' => array('<controller>Json/index', 'verb'=>'GET'),

il path api/order/index funziona, ma ovviamente api/order no.

Mi dite dove mi sto incartando? ???

Ho notato una cosa

Così funziona il primo path "List" ma non il "Create" e tutti gli altri.




'rules'=>array(

    // REST patterns

    'api/<controller>' => array('<controller>Json/index', 'verb'=>'GET'), // List

    'api/<controller:\w+>' => array('<controller>Json/create', 'verb'=>'POST'), // Create

    'api/<controller:\w+>/<id:\d+>' => array('<controller>Json/view', 'verb'=>'GET'), //Read

    'api/<controller:\w+>/<id:\d+>' => array('<controller>Json/update', 'verb'=>'PUT'), //Update

    'api/<controller:\w+>/<id:\d+>' => array('<controller>Json/delete', 'verb'=>'DELETE'), //Delete

    // WEB patterns

    '<controller:\w+>/<id:\d+>'=>'<controller>/view',

    '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',

    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',

),



Così




'rules'=>array(

    // REST patterns

    'api/<controller>' => array('<controller>Json/index', 'verb'=>'GET'), // List

    'api/<controller:\w+>' => array('<controller>Json/create', 'verb'=>'POST'), // Create

    'api/<controller>/<id:\d+>' => array('<controller>Json/view', 'verb'=>'GET'), //Read

    'api/<controller:\w+>/<id:\d+>' => array('<controller>Json/update', 'verb'=>'PUT'), //Update

    'api/<controller:\w+>/<id:\d+>' => array('<controller>Json/delete', 'verb'=>'DELETE'), //Delete

    // WEB patterns

    '<controller:\w+>/<id:\d+>'=>'<controller>/view',

    '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',

    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',

),



Funzionano "List" e "Read" ma non tutti gli altri…

Se ho pattern uguali ma verb diversi mi si incartano le regexp!

Se, per fare un test, cambio l’identificatore <controller> con uno diverso per ogni pattern es.




'rules'=>array(

    // REST patterns

    'api/<list>' => array('<list>Json/index', 'verb'=>'GET'), // List

    'api/<create>' => array('<create>Json/create', 'verb'=>'POST'), // Create

    'api/<read>/<id:\d+>' => array('<read>Json/view', 'verb'=>'GET'), //Read

    'api/<update>/<id:\d+>' => array('<update>Json/update', 'verb'=>'PUT'), //Update

    'api/<delete>/<id:\d+>' => array('<delete>Json/delete', 'verb'=>'DELETE'), //Delete

    // WEB patterns

    '<controller:\w+>/<id:\d+>'=>'<controller>/view',

    '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',

    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',

),



funzionano tutti.

Non so spiegarmi il perché.

Le rules vengono inserite in un array associativo, se metti o stesso id l’ultimo si mangia i primi.

Se ti serve fare rules diverse con lo stesso pattern, usa routePattern:




    array('<controller>Json/index', 'routePattern'=>'api/<controller>', 'verb'=>'GET'), // List

    array('<controller>Json/create', 'routePattern'=>'api/<controller:\w+>', 'verb'=>'POST'), // Create

    array('<controller>Json/view', 'routePattern'=>'api/<controller>/<id:\d+>', 'verb'=>'GET'), //Read

    array('<controller>Json/update', 'routePattern'=>'api/<controller:\w+>/<id:\d+>'', 'verb'=>'PUT'), //Update

    array('<controller>Json/delete', 'routePattern'=>'api/<controller:\w+>/<id:\d+>'', 'verb'=>'DELETE'), //Delete

ottimo!

grazie

Ho parlato troppo presto, in realtà sembrano non funzionare.




'urlManager'=>array(

                'urlFormat'=>'path', 

                'showScriptName'=>false,

                'rules'=>array(

                    // REST patterns

                    array('<controller>Json/index', 'routePattern'=>'api/<controller:\w+>', 'verb'=>'GET'), // List

                    // WEB patterns

                    '<controller:\w+>/<id:\d+>'=>'<controller>/view',

                    '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',

                    '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',

                ),

            ),

api/order da sempre Unable to resolve the request "api/order".

Perche’ non usi una sola azione in cui controlli il verb?

In questa maniera eviti il problema attuale e soprattuto riduci il numero di rules, che e’ sempre una cosa buona giusta.

Non mi piace molto raggruppare action diverse e alla fine sono 8 in tutto, ma ancora sono in fase di valutazione di tutta l’implementazione restful.

Ma se hanno lo stesso nome tanto vale raggrupparle, nella action ci metti uno switch che controlla il verb.

Se lasci le url come hai intenzione di farle lo switch lo fa Yii, la differenza e’ che quello switch di sistema viene fatto ad ogni richiesta per cercare l’url e, quel che e’ peggio, per ogni link che generi.

Se sposti questa operazione nell’action sei sicuro che viene eseguita solo quando serve, ovvero solo quando devi gestire una richiesta per quella specifica action.