On Fri, Jul 25, 2008 at 07:09:58AM -0700, Bill Moseley wrote: > > I'm looking for suggestions how to best support multiple API versions > in an application. > > The API and web share many controller actions. As is not uncommon, > actions available for the API are defined with an attribute: > > sub foo : Local XMLRPC( 'foo.get' ) { > > This is great for sharing code as often the API just exposes > the same functionality as the web interface. > > > When a new version of the web application is released then all web > users see the new version at the same time. If an action in the new > version expects an additional new parameter then the form posting to > that action is modified at the same time. > > But, the API access to an application typically needs to be backward > compatible to allow API users time to update their client applications > with the newer requirements. > > So, it seems I would need multiple controller actions that are > dispatched based on some version. > > > Here's one idea I was kicking around: > > Say I have an existing controller action that is used by the web > users, but also available as an XMLRPC API method: > > sub widget : Local XMLRPC( 'widget.get' ) { > > So in a new application version that controller action is changed > and now requires a new parameter and returns new data. > > In the new version I want to support the new action but remain > backward compatible. > > # fetch widget for web and API > sub widget : Local XMLRPC( 'widget.get' ) Version( 2 ) { > > # deprecated to support old version of API > sub widget_old : XMLRPC( 'widget.get' ) Version( 1 ) {
sub widget :Local VersionedXMLRPC('widget.get') { sub widget_xmlrpc_v1 { have VersionedXMLRPC apply a custom a ction class that does ->can based dispatch, same way Catalyst::Action::REST does. Could even make XMLRPC always do that in your app, you'll need a controller base class to provide the _parse_AttrName method iether way. Seems like a bit less typing without any real loss of precision - the main action should likely fire for any version not explicitly handled for compat so no version given or a compatible newer version just happen. If you're going to assume integer versions (or some method name valid encoding of a more complex version number) you could probably instead have the action class scan the controller's entire namespace on creation with a view to making _v9 handle anything below v9 as well until it finds a more specific, lower versioned compat handler (_v3 or similar). -- Matt S Trout Need help with your Catalyst or DBIx::Class project? Technical Director http://www.shadowcat.co.uk/catalyst/ Shadowcat Systems Ltd. Want a managed development or deployment platform? http://chainsawblues.vox.com/ http://www.shadowcat.co.uk/servers/ _______________________________________________ List: Catalyst@lists.scsys.co.uk Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/ Dev site: http://dev.catalyst.perl.org/