AE
Ash Elixir•2y ago
moxley

No Absinthe schemas generated for resource

I've been using AshGraphql just fine, having created several resources that work with it. Then today, I created a new resource, and no Absinthe schemas are created from it.
20 Replies
moxley
moxleyOP•2y ago
Here's the resource:
defmodule GF.Events.Venue2 do
@moduledoc """
Venue Ash resource.
"""

use Ash.Resource,
data_layer: AshPostgres.DataLayer,
extensions: [AshGraphql.Resource]

alias GF.Repo

multitenancy do
strategy :attribute
attribute :org_id
global? true
end

postgres do
table "venues"
repo Repo
end

actions do
defaults [:create, :read, :update, :destroy]
end

relationships do
belongs_to :org, GF.Ash.Org, attribute_type: :integer
end

attributes do
integer_primary_key :id

attribute :name, :string
end

graphql do
type :venue2

queries do
get :get_ash_venue, :read
list :list_ash_venues, :read
end

mutations do
create :create_ash_venue, :create
update :update_ash_venue, :update
destroy :delete_ash_venue, :destroy
end
end
end
defmodule GF.Events.Venue2 do
@moduledoc """
Venue Ash resource.
"""

use Ash.Resource,
data_layer: AshPostgres.DataLayer,
extensions: [AshGraphql.Resource]

alias GF.Repo

multitenancy do
strategy :attribute
attribute :org_id
global? true
end

postgres do
table "venues"
repo Repo
end

actions do
defaults [:create, :read, :update, :destroy]
end

relationships do
belongs_to :org, GF.Ash.Org, attribute_type: :integer
end

attributes do
integer_primary_key :id

attribute :name, :string
end

graphql do
type :venue2

queries do
get :get_ash_venue, :read
list :list_ash_venues, :read
end

mutations do
create :create_ash_venue, :create
update :update_ash_venue, :update
destroy :delete_ash_venue, :destroy
end
end
end
And here's the test that tests it:
describe "create_venue" do
@create_venue """
mutation CreateVenue2($input: CreateVenue2Input!) {
createVenue2(input: $input) {
result {
id
name
}
errors {
message
}
}
}
"""

@tag :capture_log
test "success", ctx do
ctx = create_session_member(ctx, roles: ["content"])
input = %{name: "Test Venue"}

resp_body =
post_gql(ctx, %{
query: @create_venue,
variables: %{input: input}
})

dbg(resp_body)
end
end
describe "create_venue" do
@create_venue """
mutation CreateVenue2($input: CreateVenue2Input!) {
createVenue2(input: $input) {
result {
id
name
}
errors {
message
}
}
}
"""

@tag :capture_log
test "success", ctx do
ctx = create_session_member(ctx, roles: ["content"])
input = %{name: "Test Venue"}

resp_body =
post_gql(ctx, %{
query: @create_venue,
variables: %{input: input}
})

dbg(resp_body)
end
end
ZachDaniel
ZachDaniel•2y ago
is it in the registry?
moxley
moxleyOP•2y ago
The registry:
defmodule GF.Ash.Registry do
use Ash.Registry,
extensions: [
# This extension adds helpful compile time validations
Ash.Registry.ResourceValidations
]

entries do
entry GF.Ash.Org
entry GF.Events.Venue2
entry GF.WebComponents.WebComponent
entry GF.WebComponents.WebSite
end
end
defmodule GF.Ash.Registry do
use Ash.Registry,
extensions: [
# This extension adds helpful compile time validations
Ash.Registry.ResourceValidations
]

entries do
entry GF.Ash.Org
entry GF.Events.Venue2
entry GF.WebComponents.WebComponent
entry GF.WebComponents.WebSite
end
end
AbsintheSchema:
defmodule GfWeb.GraphQL.AbsintheSchema do
@moduledoc false
use Absinthe.Schema
@apis [GF.Ash, Corp.Ash.Api]
use AshGraphql, apis: @apis
...
defmodule GfWeb.GraphQL.AbsintheSchema do
@moduledoc false
use Absinthe.Schema
@apis [GF.Ash, Corp.Ash.Api]
use AshGraphql, apis: @apis
...
ZachDaniel
ZachDaniel•2y ago
🤔 🤔 does mix compile --force help?
moxley
moxleyOP•2y ago
I'll try that...
ZachDaniel
ZachDaniel•2y ago
you shouldn't need to do that, but its good to check
moxley
moxleyOP•2y ago
Nope, didn't help
ZachDaniel
ZachDaniel•2y ago
FWIW your test doesn't appear to be using the mutation name you shared w/ me the mutation in the resource is create_ash_venue and the test is createVenue2 could that be related?
moxley
moxleyOP•2y ago
Oh yeah, I was trying different things. Let me verify...
ZachDaniel
ZachDaniel•2y ago
might also be worthwhile to load up the gql playground to see if its there just not what you expected it to be or something
moxley
moxleyOP•2y ago
I tried that too Okay it works! Wow. I double-checked the names, but that wasn't good enough.
ZachDaniel
ZachDaniel•2y ago
classic 😆 glad its working
moxley
moxleyOP•2y ago
Thanks for checking my work!
ZachDaniel
ZachDaniel•2y ago
my pleasure 😄
moxley
moxleyOP•2y ago
@Zach Daniel One question on mutations: Why is it by default that mutations return a result and error field? I know there's the option to put the errors at the root level, but there must be some advantage for the default behavior.
ZachDaniel
ZachDaniel•2y ago
There are a couple reasons, not that they are like...huge reasons to do it this way, but its what made me choose that path 1. the errors can be typed 2. it allows us to return action specific mettadata we solved for #2 a bit differently for read actions by creating additional types, but for mutations we add a typed metadata key to the result object for example:
create :register do
metadata :token, :string, allow_nil?: false
end
create :register do
metadata :token, :string, allow_nil?: false
end
metadata just tells any consumers that the action will populate some metadata on the resource, and expresses what type it will be. So with that you'll get something like RegisterResult with types for the metadata, result and errors.
{
result: {},
metadata: {},
errors: []
}
{
result: {},
metadata: {},
errors: []
}
I'd like to make these things more flexible over time, kind of like what we did for relay support, to allow people to pick from a few different flavors, and to customize things more (like removing result objects)
moxley
moxleyOP•2y ago
Okay, thanks for the explanation. That makes sense. I'll have to chew on that a bit. From a client-side perspective, having errors come from two different places is a lot to deal with.
ZachDaniel
ZachDaniel•2y ago
yeah, I can see that. For me, I tend to treat them differently. errors that come in the response for the specific mutatiton (since you can send multiple) are usually errors I want to tell the user about in some way but actual errors imply something crashed/the internal action did not complete the process of handling the request. Regardless, the end goal is customizability, so if there is a way you'd like to see it done that doesn't match what you can get from it currently, we can make the necessary adjustments 🙂
moxley
moxleyOP•2y ago
That helps me understand the errors better. One type of error is like a 4xx error, and the other is like a 5xx error.
ZachDaniel
ZachDaniel•2y ago
Yeah. It is still possible to get sort of "something unknown went wrong", but in such a way that the system handled it

Did you find this page helpful?