ash-project / ash_json_api

The JSON:API extension for the Ash Framework
https://hexdocs.pm/ash_json_api
MIT License
56 stars 40 forks source link

Generated "links" in output does not include path to the resource and the other query entries are lost #108

Closed m0rt3nlund closed 8 months ago

m0rt3nlund commented 10 months ago

Describe the bug The generated output from a request does not include the path to the resource Also other query parameters are lost in the links

To Reproduce Run a request on a resource and inspect output

Observed output

{
  ..
  "links": {
    "first": "https://localhost:443?page[limit]=1",
    "self": "https://localhost:443?page[limit]=1",
    "next": "https://localhost:443?page[offset]=1&page[limit]=1",
    "prev": null
  }
}

Expected behavior Expects "links" to contain the path for the resource:

{
  ..
  "links": {
    "first": "https://localhost:443/api/resource?page[limit]=1",
    "self": "https://localhost:443/api/resource?page[limit]=1",
    "next": "https://localhost:443/api/resource?page[offset]=1&page[limit]=1",
    "prev": null
  }
}

** Runtime

jimsynz commented 10 months ago

Thanks for the bug report!

zachdaniel commented 10 months ago

This is interesting. I can't replicate the same issue either in test cases or in my own application.Can you provide more details?

sevenseacat commented 8 months ago

I just came to report this as well, so I guess I can provide some more info :)

main app router:

  scope "/api" do
    pipe_through [:api]

    forward "/", MyAppWeb.JsonAPIRouter
  end

JsonAPIRouter:

defmodule MyAppWeb.JsonAPIRouter do
  use AshJsonApi.Api.Router,
    apis: [MyApp.Music],
    json_schema: "/json_schema",
    open_api: "/open_api"
end

API configuration:

defmodule MyApp.Music do
  use Ash.Api, extensions: [AshGraphql.Api, AshJsonApi.Api]

resource:

defmodule MyApp.Music.Artist do
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer,
    extensions: [AshGraphql.Resource, AshJsonApi.Resource]

  json_api do
    type "artist"

    routes do
      base "/artists"

      get :read
      index :search
      ...

Visiting http://localhost:4000/api/artists calls the search action of the resource, and as part of the response, returns links like:

  "links": {
    "first": "http://localhost:4000?page[limit]=12",
    "self": "http://localhost:4000?page[limit]=12",
    "next": "http://localhost:4000?page[offset]=12&page[limit]=12",
    "prev": null
  },

So the /api/artists part of the links is missing.

Adding prefix "/api" to the API configuration doesn't seem to make a difference.

zachdaniel commented 8 months ago

@sevenseacat what happens if you don't put the router in a scope, but specify the full path instead? Or put it in a scope that just has "/"

sevenseacat commented 8 months ago

Well it has to be in a scope doesn't it? Huh... apparently it doesn't.

Either way, moving it out of the scope (or changing it to scope "/" and forward "/api") doesn't make a difference to the generated links.

ie. router:

  scope "/api" do
    pipe_through [:api]
  end

  forward "/api2", MyAppWeb.JsonAPIRouter

Visiting http://localhost:4000/api2/artists still generates links like:

"links": {
    "first": "http://localhost:4000?page[limit]=12",
    "self": "http://localhost:4000?page[limit]=12",
    "next": "http://localhost:4000?page[offset]=12&page[limit]=12",
    "prev": null
  },