graphql-erlang
graphql-erlang copied to clipboard
Make it possible to define the format of null returns
Currently when a node resolve to no data we return {ok, null}
; this is fine for an Erlang and JSON context, but if we want to use another output format, or use graphql-erlang as an interface to another system that require something else (like {ok, undefined}
) we could benefit from making this configurable.
This will have to happen when the graphql-execute finalise a value.
Maybe it will be useful to look at #88 . At the end this issue should be a better solution than that PR.
Changing the return value of graphql_execute:default_resolver/3
should do the expected result.
We have fixed one concern here because the default-resolver now lives outside the GraphQL engine. This allows a user to define their own default resolver, and it simplifies some of the work.
Furthermore, I've found two places in the type checker that needs to be addressed:
- Resolving a default value which is non_null in the specification isn't allowed to have the value
null
. But the type checker only checks fornull
. - When resolving input objects, the system checks for non-null objects by means of looking for
null
as well. The function (check_input_object_fields) doesn't have a context currently.
However, the observation we need to make is the following: GraphQL really runs on 4 entities:
- The schema. In the GraphQL spec a null here is called
null
. - The query document. These cannot contain a null value (because the client cannot input a null value). But a missing parameter is going to be translated into some kind of
null
value. - The "current object" we are working on in order to handle a query. This object should entirely be under the jurisdiction of a developer, not the GraphQL engine. Thus it may contain
nil
,NONE
or something other atom() freely. And the GraphQL shouldn't concern itself with this. - The output structure from a query resolution. This should be able to have any null type as we see fit:
nil
,NULL
,undefined
, or<<>>
etc.
A correct handling will have to understand these 4 contexts and where the change should go in. It is unlikely we should change all of them.
@gausby and I have an even better solution.
- First we need to handle #180 so we have an input null type
- Next, we should have the concept of a null-coercer, with a default implementation of
null
. The null-coercer understands how to read in null values in output and how to render null values in output.
Given this, you can alter the null-coercer and then get better Elixir support.