[Catalyst] API Versioning for Web Services

Matt S Trout dbix-class at trout.me.uk
Sat Jul 26 06:00:39 BST 2008


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/



More information about the Catalyst mailing list