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

Graphiti schema does not include endpoints with subdomain constraint #412

Open
masterT opened this issue Apr 19, 2022 · 2 comments
Open

Comments

@masterT
Copy link

masterT commented Apr 19, 2022

I'm trying to configure the Vandal UI for a Rails application, Vandal does not display any available endpoints.

Screen Shot 2022-04-19 at 15 05 37

The schema.json that Vandal fetched does not contain any endpoints.

Screen Shot 2022-04-19 at 15 11 48

I'm using a subdomain constraint on the route of my endpoints.

# config/routes.rb

constraints subdomain: 'api' do
  namespace :v3, defaults: { format: :jsonapi } do
    mount VandalUi::Engine, at: '/vandal'

    resources :accounts, only: %i[index show]
  end
end

I dig a little in the source code, and realise that the Graphiti::Schema.generate uses the Graphiti.config.context_for_endpoint.

next unless (ctx = context_for(e[:full_path], a))

def context_for(path, action)
Graphiti.config.context_for_endpoint.call(path.to_s, action)
end

Which is configured by graphiti-rails in lib/graphiti/rails/railtie.rb#L120-L139.

Graphiti.config.context_for_endpoint = ->(path, action) {
  method = :GET
  case action
    when :show then path = "#{path}/1"
    when :create then method = :POST
    when :update
      path = "#{path}/1"
      method = :PUT
    when :destroy
      path = "#{path}/1"
      method = :DELETE
  end


  route = begin
            ::Rails.application.routes.recognize_path(path, method: method)
          rescue
            nil
          end
  "#{route[:controller]}_controller".classify.safe_constantize if route
}

The problem is that in order for recognize_path to return the route for a subdomain constraint, the path should include the host (ex: http://api.example.com/v1) instead of the path (ex: /v1).

This can be easily fixed by changing the Graphiti.config.context_for_endpoint in a Rails initializer (ex: config/initializers/graphiti.rb).

Graphiti.config.context_for_endpoint = ->(path, action) {
  method = :GET
  case action
    when :show then path = "#{path}/1"
    when :create then method = :POST
    when :update
      path = "#{path}/1"
      method = :PUT
    when :destroy
      path = "#{path}/1"
      method = :DELETE
  end

+  # Add host to the path to resolve route with subdomain constraint.
+  path = 'http://api.example.com' + path.to_s

  route = begin
            ::Rails.application.routes.recognize_path(path, method: method)
          rescue
            nil
          end
  "#{route[:controller]}_controller".classify.safe_constantize if route
}

After this change, the schema contains the expected endpoints.

{
  # ...
  :endpoints => {
    :"/v3/accounts" => {
      :actions => {
        :index => {
          :resource => "V3::AccountResource"
        },
         :show => {
          :resource => "V3::AccountResource"
        }
      }
    }
  }
}

I'm wondering if some changes should be made (gem graphiti, gem graphiti-rails) so the this is handled by default. I'm opening an issue to document the issue, but also to discuss potential changes to improve Graphiti. 🙂

I know that a Resource has a base_url (through the module Graphiti::Links).

Maybe the resource base_url should prefix the endpoint full_path when calling Graphiti.config.context_for_endpoint from Graphiti::Schema.generate_endpoints. 🤔

@bilouw
Copy link

bilouw commented Mar 7, 2023

Hi,

I just faced the same problem ! Thanks for your solution, it avoid me a lot of headaches !
I have one question, do you know why the links have still localhost and doesn't use my subdomain (api) ?
image

Also, i'm agree that we maybe should make an PR to handle this case properly, without overriding the context_for_endpoint method.

@TafadzwaD
Copy link

@masterT @bilouw I ran into the same issue of empty endpoints. I have tried your solution but to no joy in my case. Any other suggestions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants