pluralize optional #247

Closed
phillpafford opened this Issue Jun 7, 2012 · 21 comments

Comments

Projects
None yet
6 participants
@phillpafford

How can I make this optional?

I don't want the pluralization to happen with auto generated routes, so:

public function getBlahAction($args)
{
    return array('response' => true);
}

should resolve to:

/blah/{args}

but is resolving to:

/blahs/{args}

if there is some documentation on retaining the singular naming, please point me to it

@ghost ghost assigned everzet Jun 11, 2012

@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Jun 11, 2012

Member

I am not sure if this makes sense. This is a convention and if you don't like it, don't use it. If we make too many things optional, we run the risks of Bundles being incompatible. So if at all we would need to offer a way to configure this on a per class level.

Member

lsmith77 commented Jun 11, 2012

I am not sure if this makes sense. This is a convention and if you don't like it, don't use it. If we make too many things optional, we run the risks of Bundles being incompatible. So if at all we would need to offer a way to configure this on a per class level.

@phillpafford

This comment has been minimized.

Show comment Hide comment
@phillpafford

phillpafford Jun 11, 2012

Thanks, I did do a little more research on this subject ( http://jasonsirota.com/all-those-sses-what-pluralization-method-do-y ). I think this is a non issue and can be closed. But as a suggestion could this be better documented? I spent half a day tracking down why all my routes where pluralized when I was expecting them to be singular.

Thanks, I did do a little more research on this subject ( http://jasonsirota.com/all-those-sses-what-pluralization-method-do-y ). I think this is a non issue and can be closed. But as a suggestion could this be better documented? I spent half a day tracking down why all my routes where pluralized when I was expecting them to be singular.

@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Jun 11, 2012

Member

its mentioned in the docs. but i guess not where you expected it. therefore it would be best if you could send us a PR with a note where you would expect it.

Member

lsmith77 commented Jun 11, 2012

its mentioned in the docs. but i guess not where you expected it. therefore it would be best if you could send us a PR with a note where you would expect it.

@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Jun 11, 2012

Member

don't be shy .. just click on "edit" on one of them .. and add the text. that way you will fork and create a PR in one swoop :)

Member

lsmith77 commented Jun 11, 2012

don't be shy .. just click on "edit" on one of them .. and add the text. that way you will fork and create a PR in one swoop :)

@phillpafford

This comment has been minimized.

Show comment Hide comment
@phillpafford

phillpafford Jun 19, 2012

I did find a way to get the functionality desired, in routing.yml I added this

NOTE: _my and my are referring to MyController
NOTE: function is referring to getFunction

_my:
    pattern:      /path/to/my/function/{arg}
    defaults:     { _controller: ACMEMyBundle:MyController:getFunction }
    requirements:
        _method:  GET

MyController.php

class MyController extends Controller
{
    public function getFunction($arg)
    {
        return new Response(json_encode(array('response' => 'Arg Passed: '.$arg)));
    }

The check if the route is configured correctly using this command on the command line

php app/console route:debug

You should see something like:

[router] Current routes
Name                           Method Pattern
_my                  GET    /path/to/my/function/{arg}


I did find a way to get the functionality desired, in routing.yml I added this

NOTE: _my and my are referring to MyController
NOTE: function is referring to getFunction

_my:
    pattern:      /path/to/my/function/{arg}
    defaults:     { _controller: ACMEMyBundle:MyController:getFunction }
    requirements:
        _method:  GET

MyController.php

class MyController extends Controller
{
    public function getFunction($arg)
    {
        return new Response(json_encode(array('response' => 'Arg Passed: '.$arg)));
    }

The check if the route is configured correctly using this command on the command line

php app/console route:debug

You should see something like:

[router] Current routes
Name                           Method Pattern
_my                  GET    /path/to/my/function/{arg}


@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Jun 20, 2012

Member

Without the pluralization we wouldn't know the relationship between the methods which is going to be important for example when implementing #52. furthermore its a key idea of REST that we have the GET for a single element in a collection be in a "subdir" of the collection itself.

So if you do "proper" REST then /member/{id}.{_format} would be oddly named but it would be actually wrong if your collection itself wouldn't then also reside under /member{.format}.

The gist of all of this is .. the solution as is isn't so much about convenience than it is about enforcing people actually following REST principles.

if all you want is to convert method names to routes, then I would suggested you create an alternative solution.

i am closing this ticket .. if anyone feels like there is something to add to the docs to make the current behavior more clear please do so in a PR

Member

lsmith77 commented Jun 20, 2012

Without the pluralization we wouldn't know the relationship between the methods which is going to be important for example when implementing #52. furthermore its a key idea of REST that we have the GET for a single element in a collection be in a "subdir" of the collection itself.

So if you do "proper" REST then /member/{id}.{_format} would be oddly named but it would be actually wrong if your collection itself wouldn't then also reside under /member{.format}.

The gist of all of this is .. the solution as is isn't so much about convenience than it is about enforcing people actually following REST principles.

if all you want is to convert method names to routes, then I would suggested you create an alternative solution.

i am closing this ticket .. if anyone feels like there is something to add to the docs to make the current behavior more clear please do so in a PR

@lsmith77 lsmith77 closed this Jun 20, 2012

@phillpafford

This comment has been minimized.

Show comment Hide comment
@phillpafford

phillpafford Jun 20, 2012

lsmith77 could you please point out the REST standard / principle you are referring to? I understand you are trying to create a standard in how the REST calls are generated but something of a Vanity URL would also be beneficial

lsmith77 could you please point out the REST standard / principle you are referring to? I understand you are trying to create a standard in how the REST calls are generated but something of a Vanity URL would also be beneficial

@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Jun 20, 2012

Member

oh and as you pointed out .. if you don't want to follow this standard .. just hand code your route

Member

lsmith77 commented Jun 20, 2012

oh and as you pointed out .. if you don't want to follow this standard .. just hand code your route

@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Jun 20, 2012

Member

so yeah .. in that case i recommend you either use SensioFrameworkExtraBundle to define additional routes via annotations, hardcode the routes manually or use FOSRestBundle as an example to create your own route loader.

Member

lsmith77 commented Jun 20, 2012

so yeah .. in that case i recommend you either use SensioFrameworkExtraBundle to define additional routes via annotations, hardcode the routes manually or use FOSRestBundle as an example to create your own route loader.

@InputOutput

This comment has been minimized.

Show comment Hide comment
@InputOutput

InputOutput Dec 20, 2012

Not wanting to dive into the discussion on if you should even want to enforce REST principles in this way but AFAIK there is no rule that a RESTfull URL should be in english.

Appending an 's' to nouns in any language but English results in total gibberish. Even in English there are so many exceptions to the pluralization rule that I certainly wouldn't take this route (pun intented).

A way of overriding this behaviour on a per route basis would make the FOSrest bundle even more usefull, in my opinion.

Not wanting to dive into the discussion on if you should even want to enforce REST principles in this way but AFAIK there is no rule that a RESTfull URL should be in english.

Appending an 's' to nouns in any language but English results in total gibberish. Even in English there are so many exceptions to the pluralization rule that I certainly wouldn't take this route (pun intented).

A way of overriding this behaviour on a per route basis would make the FOSrest bundle even more usefull, in my opinion.

@dalibor983

This comment has been minimized.

Show comment Hide comment
@dalibor983

dalibor983 Jul 17, 2013

It will be nice if there is an option to tell FOSRestBundle to generate singular paths for routes.

It will be nice if there is an option to tell FOSRestBundle to generate singular paths for routes.

@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Jul 17, 2013

Member

this partially related to #479

the thing is that what we are doing here is trying to ease one common use case. if we add a bazillion options and config steps .. then the question is how much easier we are making any use case. after all its still possible to define individual routes.

i am however open to exploring making more things in this area configurable .. but ideally any other approach should be based on a common use case. the common approach is what i see as the most common way to handle (english) REST APIs. i do not want to support all possible permutations of what someone might be doing for one project.

Member

lsmith77 commented Jul 17, 2013

this partially related to #479

the thing is that what we are doing here is trying to ease one common use case. if we add a bazillion options and config steps .. then the question is how much easier we are making any use case. after all its still possible to define individual routes.

i am however open to exploring making more things in this area configurable .. but ideally any other approach should be based on a common use case. the common approach is what i see as the most common way to handle (english) REST APIs. i do not want to support all possible permutations of what someone might be doing for one project.

@dalibor983

This comment has been minimized.

Show comment Hide comment
@dalibor983

dalibor983 Jul 17, 2013

If FOSRestBundle generates routes based on controller name (UserController) or by annotation (@routeresource(User)) why links must be started with "users" instead of "user"?

With "user" we also can create all of those restful routes https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/Resources/doc/5-automatic-route-generation_single-restful-controller.md

In my case I have "BlogController" and I get all routes with "blogs" and this will be much better with "blog".

If FOSRestBundle generates routes based on controller name (UserController) or by annotation (@routeresource(User)) why links must be started with "users" instead of "user"?

With "user" we also can create all of those restful routes https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/Resources/doc/5-automatic-route-generation_single-restful-controller.md

In my case I have "BlogController" and I get all routes with "blogs" and this will be much better with "blog".

@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Jul 17, 2013

Member

again .. the point is to support a specific convention. its impossible to provide a convention based solution based on individual preferences. but like i said .. i am open to consider adding options to deal with another commonly used convention for building REST URLs.

So the point is .. do not argue about a specific case. find me a well respected and documented "standard" (github seems to uses plurals for collection lists and singular for individual items in collections) and we can talk about supporting that.

That being said .. with #392 there are now ways to configure the pluralization. unfortunately that PR didn't document how to do this ..

Member

lsmith77 commented Jul 17, 2013

again .. the point is to support a specific convention. its impossible to provide a convention based solution based on individual preferences. but like i said .. i am open to consider adding options to deal with another commonly used convention for building REST URLs.

So the point is .. do not argue about a specific case. find me a well respected and documented "standard" (github seems to uses plurals for collection lists and singular for individual items in collections) and we can talk about supporting that.

That being said .. with #392 there are now ways to configure the pluralization. unfortunately that PR didn't document how to do this ..

@dalibor983

This comment has been minimized.

Show comment Hide comment
@dalibor983

dalibor983 Jul 17, 2013

@lsmith77 thanks for this information.

For everyone who wants to change pluralization in generated routes, you can do this by replacing "fos_rest.service.inflector" service with your implementation of "fos_rest.inflector.doctrine" service by creating new class that implements "FOS\RestBundle\Util\Inflector\InflectorInterface", than define service of this class with name e.g. "my_fos_rest.inflector.doctrine" and simply set parameter in config.yml like this:

fos_rest:
    service:
        inflector: my_fos_rest.inflector.doctrine

@lsmith77 thanks for this information.

For everyone who wants to change pluralization in generated routes, you can do this by replacing "fos_rest.service.inflector" service with your implementation of "fos_rest.inflector.doctrine" service by creating new class that implements "FOS\RestBundle\Util\Inflector\InflectorInterface", than define service of this class with name e.g. "my_fos_rest.inflector.doctrine" and simply set parameter in config.yml like this:

fos_rest:
    service:
        inflector: my_fos_rest.inflector.doctrine
@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Jul 17, 2013

Member

can you send a PR with some additions to the docs? i guess in the view chapter ..

Member

lsmith77 commented Jul 17, 2013

can you send a PR with some additions to the docs? i guess in the view chapter ..

@hussfelt

This comment has been minimized.

Show comment Hide comment
@hussfelt

hussfelt Sep 16, 2014

Contributor

@lsmith77 I can't find any docs relating to this - but it works. Are you still in need of a PR or am I looking in the wrong place?

Contributor

hussfelt commented Sep 16, 2014

@lsmith77 I can't find any docs relating to this - but it works. Are you still in need of a PR or am I looking in the wrong place?

@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Sep 16, 2014

Member

the above comment is a nice starting point. so just take that and add it to chapter 5

Member

lsmith77 commented Sep 16, 2014

the above comment is a nice starting point. so just take that and add it to chapter 5

@hussfelt

This comment has been minimized.

Show comment Hide comment
@hussfelt

hussfelt Sep 17, 2014

Contributor

Done, referred the other related tickets as well - so that someone possibly can create an interface supporting Spanish or other languages. Great work guys!

Contributor

hussfelt commented Sep 17, 2014

Done, referred the other related tickets as well - so that someone possibly can create an interface supporting Spanish or other languages. Great work guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment