How to configure urlManager to use rest api whith string id

Hi guys,

In Yii2 advanced I have the following case: I have a rest api that work using string code as id

Is there a way to configure urlManager, add a class so that the URL to be something like:

http://www.domain.com/[user]/[ABCDEFG] ?

I have created a rest api using this wiki:

http://www.yiiframework.com/wiki/748/building-a-rest-api-in-yii2-0/

The code is there:

https://github.com/sirinibin/yii2rest/blob/master/UserController.php

My problem is into function public function actionView($id)

my $id is a string ([size=2]ABCDEFG)[/size]

[size=2]

[/size]

At the moment if I connect on

http://www.domain.com/[user]/[1]

the rest api work,

but if I use:

http://www.domain.com/[user]/[ABCDEFG]

i got the error:

Not Found (#404)

i tried to configure into /config/web.php file





    'components' => [

        'urlManager' => [

            'enablePrettyUrl' => true,

		'showScriptName'=>false, //Non voglio visualizzare index.php

            'rules' => [            

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

            ],

        ],

    ],



but this method is wrong because i can use only method view

and i cannot use other methods:

‘create’=>[‘post’],

‘update’=>[‘post’],

‘delete’ => [‘delete’],

‘deleteall’=>[‘post’],

How can I configure the url manager?

ouch!

It’s probably better if you look into the REST classes now provided that ease a LOT the work you’re doing, like ages. You probably have to write one or two lines of code overall:

http://www.yiiframework.com/doc-2.0/guide-rest-quick-start.html

discard the other guide, it’s become obsolete.

The other guide, use $id as a number.

I need to work with $id as string

So my problem remains

which is fine, once you’ve adjusted your controller to extend from the yii\rest\ActiveController you should have /api/users/<id> working without throwing a 404.

After that you can override the actions() method and unset the action you want to override, and then it will automatically pick the action method you’ve implemented in the controller, similar to the following:




    public function actions()

    {

        $actions = parent::actions();


        unset($actions['view']);


        return $actions;

    }


    public function actionView($id)

    {

        if ($id == Yii::$app->user->getId()) {

            return User::findOne($id);

        }

        throw new HttpException(404);

    }



You need to specify anyway the additional routes for the routes you want to support:




        'urlManager' => [

            'enablePrettyUrl' => true,

            'showScriptName' => false,

            'enableStrictParsing' => true,

            'rules' => [

                [

                    'class' => 'yii\rest\UrlRule',

                    'controller' => 'api/user',

                ],

                '/' => 'site/index',

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

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

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

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

            ]

        ],



for the action to accept different parameters you need to define ‘patterns’ as well within the first rule.

Try to do it one step at a time so you can understand where things get awry.

1 Like

I just noticed that I said something wrong in my previous post:

to change or add new endpoints you have to configure the “extraPatterns” variable: in the guide it’s not particularly clear and it seems like ‘patterns’ lets you redefine existing routes, while it seems like it will just reset them (just a guess).

So in your case, you would have something like:




            'rules' => [

                [

                    'class' => 'yii\rest\UrlRule',

                    'controller' => 'api/user',

                    'extraPatterns' => ['GET {username}' => 'view']

                ],



Since you can’t use {id}, as it’s defined as a numeric value, you need to create a new one, {username}.

This hasn’t been defined and it should end in an additional variable called ‘tokens’ together with the already existing definition of “{id}”.




'tokens' => [

    '{id}' => '<id:\\d[\\d,]*',

    '{username}' => '<username:\\w+>'

]



I hope this clears up things.

Since I am newbie Yii2,

can you explain in what file should I put this last change?

I have founded the solution in this tutorial for setup restful api with yii2




                [

                    'class' => 'yii\rest\UrlRule',

                    'controller' => 'user',   // our country api rule,

                    'pluralize'=>false,

                    'tokens' => [

                        '{id}' => '<id:\\w+>'

                    ]

                ],                



1 Like

nice, good you found out the solution.

Just a word of advice: as ID is normally used to indicate a numeric representation of a model, it might have been best to add a new token rather than change the semantic meaning of “id”. This might be quite important if you’re generating the documentation off your code.

since The Peach helped me with exact this problem today in #yii IRC, I just want to add my learnings to this topic.

I needed th exact same thing as Giancarlo, but with two Routes. One for a string Key, and one for a string Hash to identify a resource.

These are my extraPattern an token definition




'extraPatterns' => [

    	'GET {key}' => 'view-key',

    	'GET {hash}' => 'view-hash'

],

'tokens' => [

    	'{id}' => '<id:\\d[\\d,]*>',

    	'{key}' => '<key:[a-zA-Z0-9\\-]{8}>',

    	'{hash}' => '<hash:[a-zA-Z0-9\\-]{32}>',

],



and in my ActiveController I added the following actions:




public function actionViewKey($key)

{

	$user = \app\models\User::findOne(['key' => $key]);

	if ($user) {

    		return $user;

	}

	throw new HttpException(404);

}


public function actionViewHash($hash)

{

	$user = \app\models\User::findOne(['hash' => $hash]);

	if ($user) {

    		return $user;

	}

	throw new HttpException(404);

}



I am also new to Yii, but not new to Web application Frameworks in general. I also had a srtuggle to set up RESTful Api’s that had to use modules. Came accross many links including the above you have given. During Christmas holiday I was free and had some time to go through the Yii documentation for half a day, and saw the same it in the Yii documentation yiiframework.com/doc-2.0/guide-rest-quick-start.html under RESTFUL Web Services, thereafter, setup my API server!!! I guess I just needed some quiet time to read through the documentation, it would have saved me 2 weeks of struggle and googling. :)