Can you explain this? Natural way of dealing with URL have been using query params. even
users/1
treats 1 as query param id, set by the rules. What do you mean that it is a natural way?
Well not exactly. users/1
is not considered as a query parameter, otherwise Yii2 would inject it as such in your request. The 1
is a route parameter / url segment, by that definition it is injected into your URL manager urlManager->getRouteParams()
thus injected into your controller action.
REST API’s always use users/1
rather than users/?userId=1
. That was my entire point.
How is that easier given the OPs struggles with the same? He need to do some configs while with query params no confg is needed. How is that easier?
It is “easier” because your routes can be better structured. Take a look at your REST rules every rule behind a user/{id}/path
will directly deal with a certain user. There are REST standards and everyone using the API including the OP will know
users/1/deactivate
will deactivate that user. As soon as you have 10+ requests in your controller for several different things with a single or multiple users it is much more obvious what each endpoint does. You don’t have grab the ID
in each single request and validate it and you cannot forget what path/route parameters are optional.
For example if your userIds are numbers, there is no way someone could access your endpoint with users?userId=foo
since Yii2 will not even route to it. Keep in mind those are always small examples but I deal with API’s with 200+ endpoints every day with several different paths. Having your endpoints (especially longer one) in such a structual way helps everyone in the team + the people using the API.
For example: POST users/1/invite-to-group/3
everyone would easily understand, that a user with ID 1 will be invited to group with id 3. When you take a look at your ruleset you see what needs to be done.
The other way would be POST users/invite-to-group
that could result in users/invite-to-group?userId=1&groupId=3
or users/invite-to-group?id=1&groupId=3
or something else.
As of validation, shouldn’t app depend on model validation than URL one?
Especially to this: it depends and in the end it not a this or that… sometimes it can totally rely on both. What if you don’t do anything with a model in your request… for example what if you just want to send an invitation request in your API or some sort of info mail? There is no need to create a model just to validate the data for one single request if all you want is a regex.
Again: I’m not talking about one single request in one single controller. I’m talking about best practices when you have a really large API with several hundret endpoints.
In the end the OP had only one single error / understood one thing wrong that is easily fixable. They didn’t struggle hard or something like this. One hint and they are fine.