Grape: API version not found when api nested

Created on 24 Apr 2014  路  8Comments  路  Source: ruby-grape/grape

I have two api(APIOne and APITwo) mounted in API, which is mounted in routes, but when I access http://lvh.me:3000/one/v1/hello, I got 404 API Version Not Found.

class API < Grape::API
  mount APIOne => '/one'
  mount APITwo => '/two'
end
class APIOne < Grape::API
  version 'v1', :using => :path

  get '/hello' do
    'hello'
  end
end
class APITwo < Grape::API
  version 'v1', :using => :path

  get '/world' do
    'world'
  end
end
Testgrape::Application.routes.draw do
  mount API, :at => "/"
end

I have traced the code about parsing path, I found problem is here https://github.com/intridea/grape/blob/master/lib/grape/middleware/versioner/path.rb#L34 The path here is /one/v1/hello, then potential_version = pieces[1], potential_version got one, instead of v1.

confirmed bug

Most helpful comment

I run into this problem too, at last, I use prefix method to solve it:

class API < Grape::API
  mount APIOne => '/'
  mount APITwo => '/'
end
class APIOne < Grape::API
  prefix: :one
  version 'v1', :using => :path

  get '/hello' do
    'hello'
  end
end
class APITwo < Grape::API
  prefix: :two
  version 'v1', :using => :path

  get '/world' do
    'world'
  end
end
Testgrape::Application.routes.draw do
  mount API, :at => "/"
end

then, you can access http://localhost:3000/one/v1/hello

All 8 comments

Looks like a legit bug. There should be a way to repro it with a single API and just looking for that potential version value. Would appreciate a failing spec to start.

@yanguango Shouldn't it be

get 'hello' do
  'hello'
end

I think the / is why you are getting a 404

I hit this as well and this was my workaround:

class APIOne < Grape::API
  # version 'v1', :using => :path

  namespace :v1 do
    get '/hello' do
      'hello'
    end
  end
end

Bump? Maybe we can get a spec for this. Still think it's a bug.

Facing the similar issue.

class Base < Grape::API
  version 'v1', :using => :path
  namespace :aaa do
    get '/ping' do
      'pong'
    end
  mount Bbb => 'bbb'
  end
end

In this case, aaa's path is /v1/aaa/ping, but bbb's path becomes /bbb/v1/foo.

A quick way around this issue is by mounting in the routes file.

Rails.application.routes.draw do
  mount API::AAA::Base => '/aaa'
  mount API::BBB::Base => '/aaa/bbb'
         # OR
  mount API::AAA::Base => '/aaa'
  mount API::BBB::Base => '/bbb'
end

I run into this problem too, at last, I use prefix method to solve it:

class API < Grape::API
  mount APIOne => '/'
  mount APITwo => '/'
end
class APIOne < Grape::API
  prefix: :one
  version 'v1', :using => :path

  get '/hello' do
    'hello'
  end
end
class APITwo < Grape::API
  prefix: :two
  version 'v1', :using => :path

  get '/world' do
    'world'
  end
end
Testgrape::Application.routes.draw do
  mount API, :at => "/"
end

then, you can access http://localhost:3000/one/v1/hello

Confirmed this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dblock picture dblock  路  7Comments

TangMonk picture TangMonk  路  8Comments

davidmccoy picture davidmccoy  路  3Comments

Legogris picture Legogris  路  6Comments

dmmcgee picture dmmcgee  路  6Comments