Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query param fetcher #185

Merged
merged 49 commits into from
May 16, 2012
Merged

Query param fetcher #185

merged 49 commits into from
May 16, 2012

Conversation

lsmith77
Copy link
Member

@lsmith77 lsmith77 commented Feb 7, 2012

@lsmith77
Copy link
Member Author

lsmith77 commented Feb 7, 2012

maybe instead of a listener we can use a param converter:
http://symfony.com/doc/2.0/bundles/SensioFrameworkExtraBundle/annotations/converters.html

@stof
Copy link
Member

stof commented Feb 7, 2012

does the QueryParam stuff depend on FrameworkExtraBundle currently ?

@lsmith77
Copy link
Member Author

lsmith77 commented Feb 7, 2012

no .. currently it does not. but i don't really like having to use a listener to set the request attribute.

throw new \InvalidArgumentException('No _controller for request.');
}

if (false !== strpos($_controller, '::')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you leverage the ControllerResolver ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah maybe ..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking at the code it seems like it would be inefficient for the case when the controller is not implemented as a service. but it looks like we are lacking support for a:b:c notation atm.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be more dry and future proof

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok .. we should now cover all the cases

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah it would .. but i don't think the overhead makes this legitimate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could the controller event help with efficiency ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm it could be a possibility. in that case we would move the other listener from a request listener to a controller listener as well. in that case of course the parameters would no longer be available in any listeners run before the controller, but i guess that would be ok.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok .. i have an implementation using a controller event .. will push that into a new branch

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see #186

public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$request->attributes->set('queryFetcher', $this->container->get('fos_rest.request.query_fetcher'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need a listener, can't it be lazy loaded (just a thought, too late to check for now)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need a listener to set the request attribute, so that it can be injected via the action signature, which is imperative to controllers that do not inject the DIC ..

@vicb
Copy link
Contributor

vicb commented Feb 9, 2012

Some thoughts:

Is the queryFetcher a good idea ? Let's imagine I do some processing in my controller based on the query parameters and then I call doSomeGreatStuff($request). This function would get the query parameters as $request->query->... and then we have a mismatch. Would it be possible to drop the queryFetcher and replace (or update) the query parameter bag instead so that the API does not get changed ?

I can imagine some day we have a router component that is aware of the query parameters. This PR could not work as the parameters are processed in the controller only. So I would prefer if the changes are moved to the router layer.

@lsmith77
Copy link
Member Author

lsmith77 commented Feb 9, 2012

Overriding the Request parameter bag would remove the need to set the request attribute. How would it behave in that case though? I guess it would then only overload get() to set the default from the annotation (what would happen if a default is passed?) and execute the given requirements checks from the annotation?

@lsmith77
Copy link
Member Author

lsmith77 commented Feb 9, 2012

the other question would be where and when do we override the default parameter bag? would this require a custom Request class or a listener again?

@vicb
Copy link
Contributor

vicb commented Feb 9, 2012

@lsmith77

  • What I can imagine is to update the parameters in the bag and then use the bag as before.
  • I would go for the router layer for the reason explained in my previous message. I had first thought of a custom bag class but I don't even think it is necessary (see my point above).

@lsmith77
Copy link
Member Author

lsmith77 commented Feb 9, 2012

Well I see some major issues here:

  1. it would mean we do a lot of work that may not become necessary
  2. if we do it in the router, then we will have the issue with determining the class/method again

@lsmith77
Copy link
Member Author

ok .. i have implemented the option of forcing the query params to be set as attributes. on conflict it throws an exception. however we also need to improve the route generation to skip any configured query parameter.

@lsmith77
Copy link
Member Author

btw .. just FYI .. you can always fork this branch and submit PRs back to this branch if you have ideas for improvements. for example it would be cool of someone could fix the above noted issue with using query params in the method signature causing them to be put into the route.

@lsmith77
Copy link
Member Author

nevermind .. already took care of it ..
anything else people think should be done?

@lsmith77
Copy link
Member Author

main thing missing now are docs ..

@stof
Copy link
Member

stof commented May 15, 2012

@lsmith77 As I already said a while ago, I think you should add an interface for the QueryParamReader and use it in the typehints, to allow people to replace the implementation if they want.

@lsmith77
Copy link
Member Author

QueryParamReader or QueryFetcher? Anyway, I will leave that to who ever wants to make the first alternative implementation :)

@stof
Copy link
Member

stof commented May 15, 2012

probably both :)
But I was talking about the reader first, thus allowing people to write an implementation reading from elsewhere than annotations if they don't like annotations

@@ -39,6 +39,7 @@ public function getConfigTreeBuilder()

$rootNode
->children()
->scalarNode('query_fetcher_listener')->defaultValue(false)->end()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't it be a booleanNode ? And you could use defaultFalse()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, it is not a boolean. But you should probably limit the possible values

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whats the syntax for that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

->scalarNode('query_fetcher_listener')->defaultFalse()
->validate()
->ifNotInArray($this->forceOptionValues)
->thenInvalid('The query_fetcher_listener option does not support %s. Please choose one of '.json_encode($this->forceOptionValues))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing one indentation level

lsmith77 added a commit that referenced this pull request May 16, 2012
@lsmith77 lsmith77 merged commit 0aa7534 into master May 16, 2012
@schmittjoh
Copy link
Contributor

About silently setting the default value on validation failure, would it not make more sense to redirect to the URL with the default value? Also in terms of SEO, and duplicate content, this seems more sensible, no?

@lsmith77
Copy link
Member Author

i thought about that too .. we could provide such an option as part of the listener eventually. it should of course only be down for proper GET requests. however i don't think that query parameters are that important for SEO, but it is relevant for caches i guess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.