-
Notifications
You must be signed in to change notification settings - Fork 529
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
Links broken when used with scope module:
routes
#591
Comments
👍 I have this issue as well, except I use my version in the url instead of the 'api' namespace. routes.rb
In the JSON, I'm getting links like:
When they should look like:
|
Also related to: It would be nice to have a solution to handle this as we also version our API via headers and do not include the version in the path. |
👍 @mitnal: Could you post the code for the monkey patch? Like you say, it's not ideal, but it's better than nothing at the moment. Thanks in advance! |
Borrowing from the gem's I'm matching the slash at the end because doing the one at the beginning would catch the '/api' in http://api.example.com. # test/lib/jsonapi_test.rb
require 'test_helper'
class JSONAPITest < ActiveSupport::TestCase
def setup
@base_url = "http://example.com"
@route_formatter = JSONAPI.configuration.route_formatter
@search = searches(:exact) # Grabs one of my fixtures
end
test "route without /api in path" do
primary_resource_klass = API::SearchResource
config = {
base_url: @base_url,
route_formatter: @route_formatter,
primary_resource_klass: primary_resource_klass,
}
builder = JSONAPI::LinkBuilder.new(config)
source = primary_resource_klass.new(@search, nil)
expected_link = "#{ @base_url }/searches/#{ source.id }"
assert_equal expected_link, builder.self_link(source)
end
end # lib/extensions/jsonapi.rb
module JSONAPI
class LinkBuilder
private
def formatted_module_path_from_class(klass)
scopes = module_scopes_from_class(klass)
unless scopes.empty?
# The Main Hack: adding the #gsub
"/#{ scopes.map(&:underscore).join('/') }/".gsub(/api\//, '')
else
"/"
end
end
end
end |
Since I'm not super familiar with Rails' internals, I'm not entirely clear how we would go about solving this. @mitnal et al, do you know where this lives, and what we'd need to add to solve the general case here? |
@beechnut: I have a very simple workaround and it just ignores module JSONAPI
class LinkBuilder
def formatted_module_path_from_class(klass)
'/api/'
end
end
end I just checked and it should be possible to create links via Rails but I do not know why we need this big LinkBuilder klass. I assume there is some hidden complexity. What I testes was the following: Routes: namespace :api do
scope module: :v1, constraint: ApiConstraint.new(version: 1) do
jsonapi_resources :my_resource
end
end Resource: module Api
module V1
class MyResource < JSONAPI::Resource
model_name 'MyResourceModel'
[...]
end
end
end Rails Console: app.url_for(Api::V1::MyResource.new(MyResourceModel.last, nil)._model)
# "http://www.example.com/api/my-resource/ffd9304a-036a-4b14-a871-8e2c339d5de2" So it should be possible to somehow use Rails to create the links. Unfortunately I have no time at the moment and to be honest I do not know JSON API well enough to know all the requirements for resource linking. Also there seems to be a lot of code that is dedicated to create links and I just looked at this one method. |
Clever -- that's much simpler! Since I have both def formatted_module_path_from_class(klass)
'/'
end Also, @mitnal: a heads-up on your last comment: I think the app.url_for(Api::V1::MyResource.new(MyResourceModel.last, nil)._model) |
@beechnut thx, fixed my code snipped. |
👍 thanks for the workarounds! but a fix would be splendid |
possible related #636 |
Here's an alternate solution that removes a set of EXCLUDED_MODULES and also removes a version module by RegEx. These are unnecessary in my URLs because my
|
I think that you're on the way using app.url_for, however I'm not sure it's perfect just yet. This is mainly due to the fact that the Rails Routes have a variety of options that can be used:
Really we should be using ActionDispatch::Routing::UrlFor if we're relying on the Rails Routing engine for inbound routing and not extracting the routing to elsewhere. As such, we do need to know the controller and action to use in order to determine the route, yes? include UrlFor
url_for(controller: 'users',
action: 'new',
message: 'Welcome!',
only_path: true) @ntippie your solution looks like it will work but is highly configured and needs mapping tightly with the selected routing structure. Reading through the commentary with Devise routing (rabbit warren of #380 » rails/rails#21231 » https://github.com/plataformatec/devise/pull/3714/files ) I'm now looking into how the Routing methods of JSONAPI::Resource are dealt with. |
Hi I'm new to use jsonapi-resources. In production, should I avoid using subdomain? It hasn't solved yet. |
Does anyone have a solution for this issue yet? |
This is what I ended coming up with to fix the issue of having /api/ in the links:
|
How do you include this monkey patch? |
…d resources are correctly namespaced under api cerebris/jsonapi-resources#591
Hi, is there a solution without monkey-patching. As I understand the problem is the same I have: If in routes I have Thanks |
Hi,
we use a version parameter inside of the
Accept
header to be able to switch Api versions. The different versions are grouped in modules. And to remove these modules as namespaces from the generated URLs we usescope module:
. This works great but the problem ist that the generated links inside a response still include the module.The code just checks the module hierarchy of the resource class and completely ignores how rails generates the routes. (See: https://github.com/cerebris/jsonapi-resources/blob/master/lib/jsonapi/link_builder.rb#L102).
Also see #361 for a similar problem.
As a workaround we monkey patch the
formatted_module_path_from_class
method to return the correct path\api\
. But that is not an ideal solution.An example route file:
And an example resource:
So Rails generates routes like:
/api/my-resource
But the generated links look like this:
/api/v1/my-resource
Sascha
The text was updated successfully, but these errors were encountered: