a-chacon / oas_rails

Generate Automatic Interactive Documentation for Your Rails API
GNU General Public License v3.0
67 stars 4 forks source link

Getting exception when trying to load OAS #3

Closed Reizar closed 3 months ago

Reizar commented 3 months ago

Hi,

First off thank you for releasing and working on this gem. I'm eager to give it a try, however I'm getting an error when I try running and accessing the docs.

Steps I followed:

  1. Added gem and ran bundle install
  2. Added mount call to routes
  3. Ran command to generate config
  4. Started server and tried accessing /docs

However I get this error ( see screenshot )

oas_rails_error

Full stack trace here:

 Started GET "/docs" for 127.0.0.1 at 2024-07-31 16:35:47 +1200
 Processing by OasRails::OasRailsController#index as HTML
   Rendering layout /Users/aaron/.rvm/gems/ruby-3.3.0/gems/oas_rails-0.2.0/app/views/layouts/oas_rails/application.html.erb
   Rendering /Users/aaron/.rvm/gems/ruby-3.3.0/gems/oas_rails-0.2.0/app/views/oas_rails/oas_rails/index.html.erb within layouts/oas_rails/application
   Rendered /Users/aaron/.rvm/gems/ruby-3.3.0/gems/oas_rails-0.2.0/app/views/oas_rails/oas_rails/index.html.erb within layouts/oas_rails/application (Duration: 0.7ms | Allocations: 51)
   Rendered layout /Users/aaron/.rvm/gems/ruby-3.3.0/gems/oas_rails-0.2.0/app/views/layouts/oas_rails/application.html.erb (Duration: 2.3ms | Allocations: 442)
 Completed 200 OK in 5ms (Views: 3.2ms | ActiveRecord: 0.0ms | Allocations: 739)

 Started GET "/docs.json" for 127.0.0.1 at 2024-07-31 16:35:47 +1200
 Processing by OasRails::OasRailsController#index as JSON
 Completed 500 Internal Server Error in 73ms (ActiveRecord: 0.0ms | Allocations: 67471)

 NameError (undefined method `new' for class `OutgoingBondTransfersController'):

 oas_rails (0.2.0) lib/oas_rails/oas_route.rb:29:in `instance_method'
 oas_rails (0.2.0) lib/oas_rails/oas_route.rb:29:in `extract_docstring'
 oas_rails (0.2.0) lib/oas_rails/oas_route.rb:23:in `extract_rails_route_data'
 oas_rails (0.2.0) lib/oas_rails/oas_route.rb:11:in `new_from_rails_route'
 oas_rails (0.2.0) lib/oas_rails/route_extractor.rb:75:in `block in extract_host_routes'
 oas_rails (0.2.0) lib/oas_rails/route_extractor.rb:75:in `map'
 oas_rails (0.2.0) lib/oas_rails/route_extractor.rb:75:in `extract_host_routes'
 oas_rails (0.2.0) lib/oas_rails/route_extractor.rb:28:in `host_routes'
 oas_rails (0.2.0) lib/oas_rails/route_extractor.rb:32:in `host_paths'
 oas_rails (0.2.0) lib/oas_rails/specification.rb:44:in `paths'
 oas_rails (0.2.0) lib/oas_rails/specification.rb:25:in `base_spec'
 oas_rails (0.2.0) lib/oas_rails/specification.rb:8:in `initialize'
 oas_rails (0.2.0) app/controllers/oas_rails/oas_rails_controller.rb:7:in `new'
 oas_rails (0.2.0) app/controllers/oas_rails/oas_rails_controller.rb:7:in `block (2 levels) in index'
 actionpack (7.1.3.4) lib/action_controller/metal/mime_responds.rb:214:in `respond_to'
 oas_rails (0.2.0) app/controllers/oas_rails/oas_rails_controller.rb:4:in `index'
 actionpack (7.1.3.4) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
 actionpack (7.1.3.4) lib/abstract_controller/base.rb:224:in `process_action'
 actionpack (7.1.3.4) lib/action_controller/metal/rendering.rb:165:in `process_action'
 actionpack (7.1.3.4) lib/abstract_controller/callbacks.rb:259:in `block in process_action'
 activesupport (7.1.3.4) lib/active_support/callbacks.rb:121:in `block in run_callbacks'
 turbo-rails (2.0.5) lib/turbo-rails.rb:24:in `with_request_id'
 turbo-rails (2.0.5) app/controllers/concerns/turbo/request_id_tracking.rb:10:in `turbo_tracking_request_id'
 activesupport (7.1.3.4) lib/active_support/callbacks.rb:130:in `block in run_callbacks'
 audited (5.6.0) lib/audited/sweeper.rb:16:in `around'
 activesupport (7.1.3.4) lib/active_support/callbacks.rb:130:in `block in run_callbacks'
 audited (5.6.0) lib/audited/sweeper.rb:16:in `around'
 activesupport (7.1.3.4) lib/active_support/callbacks.rb:130:in `block in run_callbacks'
 graphiti-rails (0.4.0) lib/graphiti/rails/debugging.rb:13:in `block in debug_graphiti'
 graphiti (1.7.3) lib/graphiti/debugger.rb:133:in `debug'
 graphiti-rails (0.4.0) lib/graphiti/rails/debugging.rb:12:in `debug_graphiti'
 activesupport (7.1.3.4) lib/active_support/callbacks.rb:130:in `block in run_callbacks'
 graphiti-rails (0.4.0) lib/graphiti/rails/context.rb:17:in `block in wrap_graphiti_context'
 graphiti (1.7.3) lib/graphiti.rb:38:in `with_context'
 graphiti-rails (0.4.0) lib/graphiti/rails/context.rb:16:in `wrap_graphiti_context'
 activesupport (7.1.3.4) lib/active_support/callbacks.rb:130:in `block in run_callbacks'
 activesupport (7.1.3.4) lib/active_support/callbacks.rb:141:in `run_callbacks'
 actionpack (7.1.3.4) lib/abstract_controller/callbacks.rb:258:in `process_action'
 actionpack (7.1.3.4) lib/action_controller/metal/rescue.rb:25:in `process_action'
 actionpack (7.1.3.4) lib/action_controller/metal/instrumentation.rb:74:in `block in process_action'
 activesupport (7.1.3.4) lib/active_support/notifications.rb:206:in `block in instrument'
 activesupport (7.1.3.4) lib/active_support/notifications/instrumenter.rb:58:in `instrument'
 activesupport (7.1.3.4) lib/active_support/notifications.rb:206:in `instrument'
 actionpack (7.1.3.4) lib/action_controller/metal/instrumentation.rb:73:in `process_action'
 actionpack (7.1.3.4) lib/action_controller/metal/params_wrapper.rb:261:in `process_action'
 searchkick (5.3.1) lib/searchkick/controller_runtime.rb:15:in `process_action'
 rescue_registry (1.0.0) lib/rescue_registry/controller.rb:24:in `process_action'
 activerecord (7.1.3.4) lib/active_record/railties/controller_runtime.rb:32:in `process_action'
 actionpack (7.1.3.4) lib/abstract_controller/base.rb:160:in `process'
 actionview (7.1.3.4) lib/action_view/rendering.rb:40:in `process'
 actionpack (7.1.3.4) lib/action_controller/metal.rb:227:in `dispatch'
 actionpack (7.1.3.4) lib/action_controller/metal.rb:309:in `dispatch'
 actionpack (7.1.3.4) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
 actionpack (7.1.3.4) lib/action_dispatch/routing/route_set.rb:32:in `serve'
 actionpack (7.1.3.4) lib/action_dispatch/journey/router.rb:51:in `block in serve'
 actionpack (7.1.3.4) lib/action_dispatch/journey/router.rb:131:in `block in find_routes'
 actionpack (7.1.3.4) lib/action_dispatch/journey/router.rb:124:in `each'
 actionpack (7.1.3.4) lib/action_dispatch/journey/router.rb:124:in `find_routes'
 actionpack (7.1.3.4) lib/action_dispatch/journey/router.rb:32:in `serve'
 actionpack (7.1.3.4) lib/action_dispatch/routing/route_set.rb:882:in `call'
 railties (7.1.3.4) lib/rails/engine.rb:536:in `call'
 railties (7.1.3.4) lib/rails/railtie.rb:226:in `public_send'
 railties (7.1.3.4) lib/rails/railtie.rb:226:in `method_missing'
 actionpack (7.1.3.4) lib/action_dispatch/routing/mapper.rb:22:in `block in <class:Constraints>'
 actionpack (7.1.3.4) lib/action_dispatch/routing/mapper.rb:51:in `serve'
 actionpack (7.1.3.4) lib/action_dispatch/journey/router.rb:51:in `block in serve'
 actionpack (7.1.3.4) lib/action_dispatch/journey/router.rb:131:in `block in find_routes'
 actionpack (7.1.3.4) lib/action_dispatch/journey/router.rb:124:in `each'
 actionpack (7.1.3.4) lib/action_dispatch/journey/router.rb:124:in `find_routes'
 actionpack (7.1.3.4) lib/action_dispatch/journey/router.rb:32:in `serve'
 actionpack (7.1.3.4) lib/action_dispatch/routing/route_set.rb:882:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/static.rb:25:in `call'
 rack-session (2.0.0) lib/rack/session/abstract/id.rb:272:in `context'
 rack-session (2.0.0) lib/rack/session/abstract/id.rb:266:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/cookies.rb:689:in `call'
 rack (3.1.7) lib/rack/method_override.rb:28:in `call'
 warden (1.2.9) lib/warden/manager.rb:36:in `block in call'
 warden (1.2.9) lib/warden/manager.rb:34:in `catch'
 warden (1.2.9) lib/warden/manager.rb:34:in `call'
 rack (3.1.7) lib/rack/static.rb:161:in `call'
 rack (3.1.7) lib/rack/static.rb:161:in `call'
 rack (3.1.7) lib/rack/static.rb:161:in `call'
 rack (3.1.7) lib/rack/etag.rb:29:in `call'
 rack (3.1.7) lib/rack/conditional_get.rb:31:in `call'
 rack (3.1.7) lib/rack/head.rb:15:in `call'
 activerecord (7.1.3.4) lib/active_record/migration.rb:655:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
 activesupport (7.1.3.4) lib/active_support/callbacks.rb:101:in `run_callbacks'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/callbacks.rb:28:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/executor.rb:14:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/actionable_exceptions.rb:16:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/debug_exceptions.rb:29:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
 rescue_registry (1.0.0) lib/rescue_registry/action_dispatch/show_exceptions.rb:11:in `call'
 rescue_registry (1.0.0) lib/rescue_registry/reset_context.rb:9:in `call'
 railties (7.1.3.4) lib/rails/rack/logger.rb:37:in `call_app'
 railties (7.1.3.4) lib/rails/rack/logger.rb:24:in `block in call'
 activesupport (7.1.3.4) lib/active_support/tagged_logging.rb:135:in `block in tagged'
 activesupport (7.1.3.4) lib/active_support/tagged_logging.rb:39:in `tagged'
 activesupport (7.1.3.4) lib/active_support/tagged_logging.rb:135:in `tagged'
 activesupport (7.1.3.4) lib/active_support/broadcast_logger.rb:240:in `method_missing'
 railties (7.1.3.4) lib/rails/rack/logger.rb:24:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/remote_ip.rb:92:in `call'
 request_store (1.7.0) lib/request_store/middleware.rb:19:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/request_id.rb:28:in `call'
 rack (3.1.7) lib/rack/runtime.rb:24:in `call'
 activesupport (7.1.3.4) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/executor.rb:14:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/static.rb:25:in `call'
 rack (3.1.7) lib/rack/sendfile.rb:114:in `call'
 actionpack (7.1.3.4) lib/action_dispatch/middleware/host_authorization.rb:141:in `call'
 rack-cors (2.0.1) lib/rack/cors.rb:102:in `call'
 railties (7.1.3.4) lib/rails/engine.rb:536:in `call'
 puma (6.4.1) lib/puma/configuration.rb:272:in `call'
 puma (6.4.1) lib/puma/request.rb:100:in `block in handle_request'
 puma (6.4.1) lib/puma/thread_pool.rb:378:in `with_force_shutdown'
 puma (6.4.1) lib/puma/request.rb:99:in `handle_request'
 puma (6.4.1) lib/puma/server.rb:464:in `process_client'
 puma (6.4.1) lib/puma/server.rb:245:in `block in run'
 puma (6.4.1) lib/puma/thread_pool.rb:155:in `block in spawn_thread'

If I run the rails console and do OutgoingBondTransfersController.new it returns an object correctly.

I am running: Rails 7.1.3.4 Ruby 3.3.0 oas_rails 0.2.0

Also if it helps with the roadmap at all, being able to filter to only include certain controllers / routes would be good. Our current API is powered by graphiti and we're not looking to add docs for those. But are working on a v2 that won't be graphiti based and we'd like to have docs for just those endpoints.

Thanks!

a-chacon commented 3 months ago

Hi @Reizar! You are welcome, and thanks to you for reporting the issue so we can build a better solution.

  1. I think you are not using your Rails app with config.api_only = true. Am I correct? So, when you add resources :outgoing_bond_transfer (Example) into your routes.rb file, your app generates routes for the entire crud thinking in a full stack app including a outgoing_bond_transfer/new path. Then the OasRails engine is looking for the def new instance method implementation, but it could find it. When you call OutgoingBondTransfersController.new you are just initializing the object and this will work in almost all ruby classes. So the solution here is to check if the route has a method implementation first, then proceed. If not, then the route will be discarded. I will be working on it asap.

  2. There is a configuration you can use. Maybe you can follow the next approach to mount the engine just for your version 2:

    • In the initializer file, config/initialzers/oas_rails.rb set the next config:
      config.api_path = "/api/v2/" # whatever your rails api path is
    • Then mount the engine into the correct namespace:
      # routes.rb
      namespace :api do
      namespace :v2 do
      mount OasRails::Engine, at: '/docs'
      end
      end
      ... 

      So after fix the first point you can try to do it. I hope will be helping you.

mathieubrunpicard commented 3 months ago

Hi, I'm trying a similar approach where I set the mount engine in a subdomain docs and I specify my ressource but I'm getting this error message : NameError - uninitialized constant Api::V2::Search

Seems there is missmatch between Search & Searches (see below)

# routes.rb
constraints subdomain: "docs" do
    mount OasRails::Engine => "/"
    resources :searches, only: [:create]
  end

I did set my config path correctly :

config.api_path = "/api/v2/" 

And I have my controller in the correct location

#app/controllers/api/v2/searches_controller.rb

  class Api::V2::SearchesController < ApplicationController
    respond_to :json
   def create
     # my method 
   end
 end

Is there something that I'm doing wrong ?