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

API versioning example #25

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

mikeraynham
Copy link

This revision adds an example script that demonstrates one method for
achieving API versioning via the Accept header.

This revision adds an example script that demonstrates one method for
achieving API versioning via the Accept header.
@autarch
Copy link
Collaborator

autarch commented Sep 3, 2014

My kingdom for some tuits. This looks good but I need to take some time to review it more thoroughly before merging.

@stevan
Copy link
Contributor

stevan commented Sep 3, 2014

Looks sensible to me, but I wonder if the use of Router::Boom is actually necessary? It kind of obscures the Web::Machine aspects.

That said, I would be okay with just explaining what Router::Boom is doing under the covers in perhaps a comment or something.

@mikeraynham
Copy link
Author

I considered adding comments to the code to explain what was happening, but decided instead to go with the style of the existing examples, in which the comments are minimal. I'm happy to add some if that helps.

I used Router::Boom as its add() method allows any value for the destination parameter. This makes it simple to iterate over a list of resources to find the first that can handle the request. If this example was accepted, I was planning to try the same approach with other routing modules, such as Web::Simple and Path::Router. My problem with those was that it took a little more work to achieve the same goal, so the example code would have obscured the Web::Machine part even more.

Alternative approaches include checking the Accept header before routing to the correct resource, or having a single resource handle multiple versions. I don't particularly like either of those alternatives. Web::Machine already handles Accept header tests, so it seems logical to let it do it. Having a single resource that handles multiple versions could end up very messy.

Before writing this, I posted a question on the Erlang Webmachine mailing list, asking how others manage API versioning via Accept headers, but I didn't get any feedback. I'd certainly be interested to learn of any better approaches.

@stevan
Copy link
Contributor

stevan commented Sep 6, 2014

I think perhaps having a few comments to explain what Router::Boom is doing would he helpful, after that, I am fine with merging this if @autarch is.

@timbunce
Copy link

timbunce commented Sep 7, 2014

I'd also like to see some comments. Not so much about Router::Boom specifically, but explaining the principle of operation and control flow, which would naturally explain how Router::Boom is being used.

The return value of the content_types_provided code refs, e.g. sub {'package : Foo::V2'} puzzle me. Is that just a dummy true value? Could sub { 1 } be used instead for greater clarity? Or am I missing something?

I'd also really like to see a section in Web::Machine::Manual about handling versioning (or perhaps a separate Web::Machine::Manual::Versioning doc) that would outline the issues and options.

@stevan
Copy link
Contributor

stevan commented Sep 8, 2014

I agree with @timbunce, it is a topic the deserves some attention as there is no "best" solution and many different solutions each with tradeoffs to them.

@mikeraynham
Copy link
Author

Thank you for your comments - I agree that explanatory notes are required. If you are happy for me to do so, I will clarify the Router::Boom example first, and then try to spend some time putting together a separate pull request that contains other examples and POD.

@timbunce

The return value of the content_types_provided code refs, e.g. sub {'package : Foo::V2'} puzzle me. Is that just a dummy true value? Could sub { 1 } be used instead for greater clarity? Or am I missing something?

The return value of the content_types_provided() is sent to STDOUT by Web::Machine, so when the example is run from the command line via curl, the package name of the resource that is handling the request is displayed:

$ curl -v http://0:5000/foo -H 'Accept: application/json; version=2'
* About to connect() to 0 port 5000 (#0)
*   Trying 0.0.0.0...
* connected
* Connected to 0 (0.0.0.0) port 5000 (#0)
> GET /foo HTTP/1.1
> User-Agent: curl/7.28.0
> Host: 0:5000
> Accept: application/json; version=2
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Mon, 08 Sep 2014 19:55:13 GMT
< Server: HTTP::Server::PSGI
< Content-Length: 17
< Content-Type: application/json; version="2"
<
* Closing connection #0
package : Foo::V2

Mike Raynham added 2 commits September 8, 2014 22:23
The example worked, but its operation and control flow was not clear.
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.

4 participants