Hi,

I am working on implementing API versioning support in FOSRestBundle via Accept 
header:
https://github.com/FriendsOfSymfony/FOSRestBundle/pull/136

Note that right now I am only looking support versioning via Accept header and 
not the ugly practice of versioning via URL's which is actually possible today 
fairly decently already.

We currently already have support for formats defined in Accept Header:
https://github.com/FriendsOfSymfony/FOSRestBundle/blob/master/EventListener/FormatListener.php

Now so far the format handling is done in a controller listener, since we 
figured that the controller might want to influence the priorities in which the 
formats are chosen instead of having to rely on global defaults (note the 
feature of the Controller overriding the global priorities isnt implemented 
yet).

Looking at supporting versioning its now dawning at me that delaying things 
until after the route has been matched is just not going to work.
So I am currently working on a RouterListener replacement that will trigger 
before the standard listener.

One of the problems here is that for API versioning its quite likely that one 
will want to split up the different versions into different Controllers, though 
in theory someone might also want to split them up into different methods in 
the same Controller. I am not so concerned with the later case though, since I 
consider that an ugly practice, but if we can support it easily fine.

Imagine the following example where the client wants xml from the 3.0 API, but 
would also be ok with getting json from the 2.0 API, but if neither two are 
available html in the 3.0 version is also ok:
Accept: application/vnd.foo+xml;version=3.0, 
application/vnd.foo+json;version=2.0, application/vnd.foo+html;version=3.0

Now if we have one Controller for the 3.0 API and one for the 2.0 API we would 
basically have to do the following:

1) find the route that matches the pattern
2) somehow get the list of Controllers based on the matched route
3) check if the 3.0 Controller supports XML for the given route
4) check if the 2.0 Controller supports JSON for the given route
5) check if the 3.0 Controller supports HTML for the given route

Now step 2) is a bit tricky. It is possible to define multiple routes with the 
same pattern, the matcher will however return the first one it finds to match. 
Note that from my understanding the list of routes passed to the matcher is 
already filtered by requirements inside the Router. So from my understanding a 
given route only has once "chance" to match and once the matcher has found a 
route its essentially done.

So given this, I think the cleanest solution would be if for one pattern I need 
to be able to specify the candidate list of all Controllers. The obvious issue 
with supporting multiple Controllers for one pattern is that right now one can 
only specify one resource per route. For example if one wants to leverage the 
FOSRestBundle route generation with annotations one can currently write:
rest:
    resource: liip_hello.rest.controller
    type:     rest

This will cause FOSRestBundle to look for the underlying class of the 
"liip_hello.rest.controller" service and parse its annotations and class 
methods to automatically generate the routes. Its also possible to configure a 
class name instead of a service and one can also specify a Yaml/Xml file 
instead.

Now in order to configure the relation between the various controllers I see 
two approaches:

1) make it possible to define multiple resources in the route which is 
implemented in https://github.com/symfony/symfony/pull/2145
2) add an annotation/yaml/xml support for the above mentioned resources to 
configure the relationship

Personally I find 1) much much cleaner, but 2) would not require any changes to 
Symfony which means it can work with Symfony 2.0

Not sure if my explanations were understandable. If I get some feedback I will 
likely start a wiki page to keep a summary of the discussion and questions with 
their answers.

regards,
Lukas Kahwe Smith
[email protected]



-- 
If you want to report a vulnerability issue on symfony, please send it to 
security at symfony-project.com

You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en

Reply via email to