Skip to content

Conversation

@jwkoelewijn
Copy link
Contributor

To call a method on a specific API version, instead of using

GET /<version>/<resource>/action, one could use

GET /<resource>/action, while supplying an HTTP Accept header:
application/vnd.<vendor>-<version>+<format>

This way it is possible to keep the URL RESTful

To use this functionality one would use:
class MyAPI < Grape::API
vendor 'grapeinc'
version 'v1.1'

get '/someaction' do
{:hello => 'world'}
end
end

To call this api, one would, for instance do
curl http://localhost:9292/someaction -H "Accept: application/vnd.grapeinc-v1.1+json"

Michael Bleigh and others added 30 commits May 26, 2011 16:32
Added Travis badge and removed Gemfile.lock
 Sorry, stole it from some other project and must have accidentally left it as linking to that project!
This allows Grape to work with ActiveResource in JSON mode. If the body contains JSON, it's contents will be added to the params hash just like if they came over the GET query string or as regular params.
Didn't account for regular POST content being in the body on some requests, even if JSON is expected as the result. It now fails gracefully.
Content type for error response
Conflicts:	lib/grape/middleware/formatter.rb
Ability to handle incoming JSON in the body
dblock and others added 24 commits August 31, 2011 04:25
Got rid of .yarddoc and updated readme to clarify exception handling.
Exposing the set of rack routes built by Grape
Call #to_xml if the content type is xml
Ability to handle incoming XML in the body
fixed rescue_from, broken when trying to rescue multiple specific exceptions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You meant to do this with vendor?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intended to add this spec right underneath it:

it 'should use HTTP_ACCEPT headers when a vendor is set' do
subject.get :hello do
"Hello"
end

 subject.vendor 'grape' subject.version 'v1' subject.get :hello do "World" end header 'Accept', 'application/vnd.grape-v1+json' get '/hello' last_response.status.should eql 200 last_response.body.should eql 'World' header 'Accept', 'application/vnd.grape-v1+json' get '/v1/hello' last_response.status.should eql 404 end` 

The last get should fail, because it defines a double version, comparable to /v1/v1/hello, which isn't defined

@dblock
Copy link
Member

dblock commented Nov 12, 2011

@mbleigh should look at this pull, thx

@mbleigh
Copy link
Contributor

mbleigh commented Nov 13, 2011

I love this feature and definitely want it in, however, I'd like to ask for a small implementation change. Rather than adding a vendor method to the API, can we do something like this instead:

class MyAPI < Grape::API version 'v1', :allow => [:header, :path], :vendor => 'grapeinc' end

Where the vendor is specified inline (and would simply default to the API classname if not specified). By default the :allow option should work both for pathname and header-based versioning, but if it is specified to one or the other it should work that way as well. This also opens the door for us to do something like request-based versioning (for subdomains like api.v1.myapp.com or something).

I can do the change myself in the next few days, but I'd also appreciate if someone else did it for me :)

@jch
Copy link
Contributor

jch commented Nov 14, 2011

@mbleigh I like the inline syntax, but the :allow option doesn't make sense to me. A Grape::API instance should choose a single way for versioning. I think it's a bad idea to allow an API to allow multiple schemes simultaneously. Instead, I think :via would be a good name for the versioning option. The default should be :header.

class OldAPI < Grape::API version 'v1', :via => :path, :vendor => 'grapeinc' end class NewAPI < Grape::API version 'v2', :via => :header, :vendor => 'grapeinc' end

This allows API's to transition to a new versioning strategy, similar to how Github's API moved from :path to :header. If that sounds good to you guys, I have a branch that does this.

One gotcha with defaulting :vendor from the class base name is NewAPI would have the wrong default base name. I think we can handle this by explaining it in the documentation.

@mbleigh
Copy link
Contributor

mbleigh commented Nov 14, 2011

I'm 👍 for using only one or the other, but let's call it :using instead of :via since I have used that option name elsewhere and it makes things more consistent. @jch if you open a separate pull request with this functionality I'll merge it in.

@jch jch closed this Jan 5, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

8 participants