[Catalyst] REST and versioning

Bill Moseley moseley at hank.org
Tue Sep 17 18:59:11 GMT 2013


On Tue, Sep 17, 2013 at 10:12 AM, John Napiorkowski <jjn1056 at yahoo.com>wrot=
e:

>
> People seem to get religious over how to version their API.  I doubt I'd
> want to take sides on this but here's how I think we could do both side
> (URL version and content type versioning


Ya, I'm swayed by the Accept: header approach because in my mind
/api/v1/account/123 and /api/v2/account/123 seems like different resources.
  (Well, I guess they are.)  So, the versions are lazy way to make a new
resource location.

And even more so, seems like a dark path to go down.  Is just that
individual resource versioned or is the entire API versioned?   And if it's
the entire API, and the app needs to support multiple versions at the same
time, then need a way for methods to "fall-back" to v1 when only a few
methods change.

Or maybe the client would have to know which methods are v2 vs. v1 and
pick-and-choose.


Realistically, the problem that would likely come up is more related to
client versioning where an old client cannot support some new feature of
the API.

For example,  say a service has a method to fetch a widget and a method to
list them.

GET /widget/123  # get widget 124
GET /widget  # list all widgets.

So, some client app is designed to list the widgets and then fetch them
(for display or whatever).

Later, the service is upgraded and adds a new *type* of widget -- and that
is a type that the existing old client app cannot support.

Does the service need to know what the client can support?

sub widget_GET : Args(0) ... {
    ...
    push @include_types, $new_widget_type if $client_version >=3D 1.1;


That's going to lead to some nasty spaghetti code over time.

Maybe not such a great example as one could argue here that the client
could GET /widget?type=3D1&type=3D2&type=3D3, but other changes might make =
that
not so easy.


In your chained example below how does that work with longer paths?

I'm trying to come up with a good example.....

/v1/document/1234   # fetch a document
/v1/document/1234/share  # list who the document is shared with.

Then what happens if it's just the share method that has a new version?



> package Myapp::Web::Controller::API;
>
> use base 'Catalyst::Controller';
>
> sub start : ChainedParent
>  PathPrefix CaptureArgs(0)
> {
>   my ($self, $ctx) =3D @_;
> }
>
>   sub version_one : Chained('start') PathPart('1') Args(0) { ... }
>
>   sub version_two : Chained('start') PathPart('2') Args(0) { ... }
>
> 1;
>
> package Myapp::Web::Controller::API::1;
>
> use base 'Catalyst::Controller';
>
> sub start : ChainedParent
>  PathPrefix CaptureArgs(0)
> {
>   my ($self, $ctx) =3D @_;
> }
>
> 1;
>
> package Myapp::Web::Controller::API::2;
>
> use base 'Catalyst::Controller';
>
> sub start : ChainedParent
>  PathPrefix CaptureArgs(0)
> {
>   my ($self, $ctx) =3D @_;
> }
>
> 1;



Bill Moseley
moseley at hank.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20130917/b12d0=
35e/attachment.htm


More information about the Catalyst mailing list