Capitalized field names yields bad error message
Defining a field with a capitalized name does not work, but the error message still suggests using the capitalized name when attempting to query it.
query do
field :Foo, type: :string, resolve: fn
_, _ -> {:ok, "Bar"}
end
end
When running the query query {Foo} this returns:
{
"errors": [
{
"message": "Cannot query field \"Foo\" on type \"RootQueryType\". Did you mean \"Foo\"?",
"locations": [
{
"line": 1,
"column": 0
}
]
}
]
}
This is definitely not helpful, but I'm not sure what alternative there is. If you're using the default adapter the name from the document "Foo" is run through the Macro.underscore function, and then compared against the field names. None match because you have "Foo" not "foo".
For the suggestions we grab all field names that are similar, and run them through Macro.camelize. We should probably be running field names through a pascalize function because fooBar is more idiomatic than FooBar, so maybe that would help.
RE "pascalize" -- Absinthe.Utils.camelize/2 has a :lower option.
How about passing type names through the to_internal_name function and producing compile time warnings when they're not equal?
The issue is that schemas are not tied to a single adapter at the moment. Adapters are set as an option on the plug, or wherever the schema is actually used against a document.
I doubt that schemas are used with multiple adapters all that often but it would be a definitely breaking change to mandate that.
Will just say I have an existing client graphQL implementation with capital words for association fields. I find it a good convention. Got the same warning as above. Would love to see a solution.
because of how Macro.underscore works the following is already possible:
defmodule Schema do
use Absinthe.Schema
query do
field :foo_bar, type: :string do
resolve fn _, _ -> {:ok, "hello"} end
end
end
end
Absinthe.run(" { FooBar }", Schema)
#=> {:ok, %{data: %{"FooBar" => "hello"}}}
I'll grant that this isn't ideal for introspection as the name of he field won't appear as FooBar. I will look into that component of it, but as far as handling queries where the documents have capitalized field names, what already exists should work.
I understand that it is important to be able to customize the name of the field. All I'm saying is that :foo_bar in that schema should be viewed as the internal identifier, not the name. From an implementation perspective the name is really anything that maps to :foo_bar via to_internal_name.
Better warnings certainly seem like a necessity.
I think having names capitalized via name: "YourName" is perfectly reasonable -- but I don't think supporting :CapitalizedIdentifiers (or CapitalizedIdentifiers) is a good idea inside Absinthe schema definitions, as it complicates query/schema name matching a fair bit (it also looks like deeply strange Elixir code). A future Absinthe release that makes schema definition more flexible (probably 1.5, as 1.4 is currently slated for null & subscriptions) without building macros would make setting names like this less tedious (similar to how middleware makes resolution more flexible).
Right yeah I think we also just need to make sure the documentation on Adapters is up to date. The whole point of the Adapter system is so that schemas can be written exactly one way without regard for how clients like to format fieldnames.
Right; names, not internal identifiers.
Scheduling addressing this as part of the "schema definition refactor" milestone.