Hi all,
I ran into this scenario while running Absinthe GQL with Phoenix, I have this query that look as a follows:
object :admin_queries do
field :get_user, non_null(:user) do
arg :input, non_null(:user_input)
resolve(&Resolvers.User.get_user/2)
end
end
input_object :user_input do
field :id, non_null(:id)
end
When I tried to run this query, I realized that is allowed for the following to pass
query getUser( {
input { id: "" }
}) {
id
name
}
correctly so, since an "" != null.
I tried to reason about how to handle the validation of id (and in extension other fields too), and I came to the following plausible solutions:
- Use middleware, but its too deep in the resolution and it was a challenge to use when you need to validate nested inputs. As an example, see what that looks like below:
defmodule Gql.Middleware.ValidateUuid do
@behaviour Absinthe.Middleware
def call(%Resolution{arguments: %{merchant_id: merchant_id}} = resolution, _),
do: validate_uuid(resolution, merchant_id, :merchant_id)
def call(%Resolution{arguments: %{delivery_id: delivery_id}} = resolution, _),
do: validate_uuid(resolution, delivery_id, :delivery_id)
def call(%Resolution{arguments: %{user_id: user_id}} = resolution, _),
do: validate_uuid(resolution, user_id, :user_id)
def call(%Resolution{arguments: %{id: id}} = resolution, _),
do: validate_uuid(resolution, id, :id)
def call(%Resolution{arguments: %{input: %{user_id: user_id}}} = resolution, _),
do: validate_uuid(resolution, user_id, :user_id)
....
- Build my own scalar type, but that would result in breaking changes in my client and the naming of the type will change, which is not ideal, within which I would use the parse macro to handle my validations.
scalar :uuid, name: "UUID" do
parse(&parse_custom/1)
end
- Handle all validation in the resolver, it would result to a lot more changes in each resolver.
My question is, is there a way to handle this more seamlessly?
In an ideal world, i think it would be awesome to have the middleware available in args or field
in input_object
.
Thanks in advance