Description
Background
My team is working on an application that depends on Grape working with rails. We tried upgrading from 1.2.2 to 1.2.5 and couldn't get the app to start.
We have relied heavily on inheriting from Grape::API::Instance instead of Grape::API to D.R.Y. our app up significantly with factory methods (details below). In our last upgrade we followed the guidelines regarding the usage of Grape::API::Instance instead of Grape::API Upgrading.md. This feels like a bug as there have only been 3 patch versions since this worked for us. We've tried compiling / mounting in different ways per the suggestions in the README and haven't been able to get it to work.
Details:
Link to Small Sample Project
Link to Diff (below)
app/api/sample/api.rb
module Sample
class Api < Grape::API::Instance
format :json
prefix :api
def self.factory(text)
get :test do
text
end
end
resource :test do
factory 'hello world'
end
end
end
config/routes.rb
Rails.application.routes.draw do
mount Sample::Api => '/'
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
Error Log
=> Booting Puma
=> Rails 6.0.2 application starting in development
=> Run `rails server --help` for more startup options
Exiting
/Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/grape-1.2.5/lib/grape/api/instance.rb:33:in `base_instance?': undefined method `base_instance' for nil:NilClass (NoMethodError)
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/grape-1.2.5/lib/grape/api/instance.rb:122:in `evaluate_as_instance_with_configuration'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/grape-1.2.5/lib/grape/api/instance.rb:104:in `nest'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/grape-1.2.5/lib/grape/dsl/routing.rb:168:in `block in namespace'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/grape-1.2.5/lib/grape/dsl/settings.rb:158:in `within_namespace'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/grape-1.2.5/lib/grape/dsl/routing.rb:165:in `namespace'
from /Users/dev_user/my_projects/tmp/rails-grape-api/app/api/sample/api.rb:13:in `<class:Api>'
from /Users/dev_user/my_projects/tmp/rails-grape-api/app/api/sample/api.rb:4:in `<module:Sample>'
from /Users/dev_user/my_projects/tmp/rails-grape-api/app/api/sample/api.rb:3:in `<main>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/kernel.rb:16:in `require'
from /Users/dev_user/my_projects/tmp/rails-grape-api/config/routes.rb:2:in `block in <main>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.2/lib/action_dispatch/routing/route_set.rb:429:in `instance_exec'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.2/lib/action_dispatch/routing/route_set.rb:429:in `eval_block'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionpack-6.0.2/lib/action_dispatch/routing/route_set.rb:411:in `draw'
from /Users/dev_user/my_projects/tmp/rails-grape-api/config/routes.rb:1:in `<main>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:54:in `load'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:54:in `load'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/application/routes_reloader.rb:41:in `block in load_paths'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/application/routes_reloader.rb:41:in `each'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/application/routes_reloader.rb:41:in `load_paths'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/application/routes_reloader.rb:20:in `reload!'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/application/routes_reloader.rb:30:in `block in updater'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.2/lib/active_support/file_update_checker.rb:83:in `execute'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/application/routes_reloader.rb:10:in `execute'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/application/finisher.rb:184:in `block in <module:Finisher>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/initializable.rb:32:in `instance_exec'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/initializable.rb:32:in `run'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/initializable.rb:61:in `block in run_initializers'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/tsort.rb:347:in `each'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/tsort.rb:347:in `call'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/initializable.rb:60:in `run_initializers'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/application.rb:363:in `initialize!'
from /Users/dev_user/my_projects/tmp/rails-grape-api/config/environment.rb:5:in `<main>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/zeitwerk-2.2.2/lib/zeitwerk/kernel.rb:23:in `require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.2/lib/active_support/dependencies.rb:325:in `block in require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.2/lib/active_support/dependencies.rb:291:in `load_dependency'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.2/lib/active_support/dependencies.rb:325:in `require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:48:in `require_relative'
from config.ru:3:in `block in <main>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/builder.rb:55:in `instance_eval'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/builder.rb:55:in `initialize'
from config.ru:in `new'
from config.ru:in `<main>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/builder.rb:49:in `eval'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/builder.rb:49:in `new_from_string'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/builder.rb:40:in `parse_file'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/server.rb:319:in `build_app_and_options_from_config'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/server.rb:219:in `app'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rack-2.0.7/lib/rack/server.rb:354:in `wrapped_app'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/commands/server/server_command.rb:77:in `log_to_stdout'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/commands/server/server_command.rb:37:in `start'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/commands/server/server_command.rb:147:in `block in perform'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/commands/server/server_command.rb:138:in `tap'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/commands/server/server_command.rb:138:in `perform'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/command/base.rb:69:in `perform'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/command.rb:46:in `invoke'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/railties-6.0.2/lib/rails/commands.rb:18:in `<main>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `block in require_with_bootsnap_lfi'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:21:in `require_with_bootsnap_lfi'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.2/lib/active_support/dependencies.rb:325:in `block in require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.2/lib/active_support/dependencies.rb:291:in `load_dependency'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-6.0.2/lib/active_support/dependencies.rb:325:in `require'
from /Users/dev_user/my_projects/tmp/rails-grape-api/bin/rails:9:in `<top (required)>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/spring-2.1.0/lib/spring/client/rails.rb:28:in `load'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/spring-2.1.0/lib/spring/client/rails.rb:28:in `call'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/spring-2.1.0/lib/spring/client/command.rb:7:in `call'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/spring-2.1.0/lib/spring/client.rb:30:in `run'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/spring-2.1.0/bin/spring:49:in `<top (required)>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/spring-2.1.0/lib/spring/binstub.rb:11:in `load'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/spring-2.1.0/lib/spring/binstub.rb:11:in `<top (required)>'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /Users/dev_user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /Users/dev_user/my_projects/tmp/rails-grape-api/bin/spring:15:in `<top (required)>'
from bin/rails:3:in `load'
from bin/rails:3:in `<main>'
Potential Solution
Interestingly enough, if you switch the call of base_instance? && lazy
to lazy && base_instsance?
on line 124 of lib/grape/api/instance.rb
(link) it fixes our issue as lazy is false in our setup. This doesn't seem like the proper fix, but if the ruby-grape team feels like it is, I'd be happy to post a PR.
Update
Just tested the setup again and it works in 1.2.2 as well as 1.2.4.