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

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

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. 🤔
I'm trying to configure the Vandal UI for a Rails application, Vandal does not display any available endpoints.
The
schema.jsonthat Vandal fetched does not contain anyendpoints.I'm using a
subdomainconstraint on the route of my endpoints.I dig a little in the source code, and realise that the
Graphiti::Schema.generateuses theGraphiti.config.context_for_endpoint.graphiti/lib/graphiti/schema.rb
Line 59 in aecf564
graphiti/lib/graphiti/schema.rb
Lines 84 to 86 in aecf564
Which is configured by graphiti-rails in lib/graphiti/rails/railtie.rb#L120-L139.
The problem is that in order for recognize_path to return the route for a subdomain constraint, the
pathshould include thehost(ex:http://api.example.com/v1) instead of the path (ex:/v1).This can be easily fixed by changing the
Graphiti.config.context_for_endpointin 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.
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 moduleGraphiti::Links).graphiti/lib/graphiti/resource/links.rb
Line 19 in 19c75b5
Maybe the resource
base_urlshould prefix the endpointfull_pathwhen callingGraphiti.config.context_for_endpointfromGraphiti::Schema.generate_endpoints. 🤔