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

Allow to define the API version where a endpoint is available #2380

Closed
jcagarcia opened this issue Nov 27, 2023 · 3 comments
Closed

Allow to define the API version where a endpoint is available #2380

jcagarcia opened this issue Nov 27, 2023 · 3 comments

Comments

@jcagarcia
Copy link
Contributor

Hey 👋

I want to share a possible improvement for reusing the same endpoint through different api versions.

I have the v1 of my API that only exposes the /foo endpoint.

class MyAPI < Grape::API
  class MyError < StandardError; end

  version 'v1', using: :path

  get '/foo' do
    { version: version }
  end
end
GET /v1/foo => { version: "v1" }

For the next version of my API, I want to add a new endpoint /var

class MyAPI < Grape::API
  class MyError < StandardError; end

  version 'v1', using: :path

  get '/foo' do
    { version: version }
  end

  version 'v2', using: :path

  get '/var' do
    { version: version }
  end
end

The examples above results in:

GET /v1/foo => { version: "v1" }
GET /v2/var => { version: "v2" }

But if i try to access the /foo endpoint in my v2 version I'm getting a 404.

GET /v2/foo => 404
GET /v2/var => { version: "v2" }

Taking a look to the code (not present in the documentation), seems I can specify multiple versions if passing an array of values

class MyAPI < Grape::API
  class MyError < StandardError; end

  version 'v1', 'v2',  using: :path

  get '/foo' do
    { version: version }
  end

  get '/var' do
    { version: version }
  end
end

So now, both endpoints are available under v1 and v2 endpoint.

GET /v1/foo => { version: "v1" }
GET /v1/var => { version: "v1" }
GET /v2/foo => { version: "v2" }
GET /v2/var => { version: "v2" }

However, this is not desired behavior. As /foo should be available in v2, but /var should not be present in /v1.

My proposal is to configure each of the endpoints for being available in the different versions of the api. For example, using a for_versions method like:

class MyAPI < Grape::API
  class MyError < StandardError; end

  version 'v1', 'v2', using: :path

  get '/foo', for_versions: ['v1', 'v2'] do
    { version: version }
  end

  get '/var', for_versions: ['v2'] do
    { version: version }
  end
end

And expecting this behavior:

GET /v1/foo => { version: "v1" }
GET /v1/var => 404
GET /v2/foo => { version: "v2" }
GET /v2/var => { version: "v2" }

What do you think about this approach?

@dblock
Copy link
Member

dblock commented Nov 28, 2023

Seems like you'd want version declarations to apply to everything below? It's ... complicated. And having version per API will quickly become messy.

I think you should try to use mount, as described in https://code.dblock.org/2013/07/19/evolving-apis-using-grape-api-versioning.html. Does that help?

@jcagarcia
Copy link
Contributor Author

Hi @dblock , as always, thanks for the feedback :)

Yes, I followed the approach you describe in your post and it perfectly works for what I was trying to achieve 👍 This makes me think that maybe this is a documentation problem (or maybe I was not able to find it?). For example, I discovered that multiple versions were allowed because I checked the code, but not in the README.

Do you think #2381 can help?

dblock added a commit that referenced this issue Nov 28, 2023
doc(#2380): Updating versioning section inside the README
@dblock
Copy link
Member

dblock commented Nov 28, 2023

Thanks for contributing the docs! I merged those, closing this issue.

@dblock dblock closed this as completed Nov 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants