graphql-php
graphql-php copied to clipboard
Ability to implement ID coercion (input and output)
Thoughts based on the spec: https://graphql.github.io/graphql-spec/June2018/#sec-ID
In general, ID
should coerce to string
on the output side and from string
or int
on the input side.
Some points on the expected behavior when coercing on input and outside side - excerpt from the spec:
Result (Output) Coercion:
[...] GraphQL servers should coerce as appropriate given the ID formats they expect. When coercion is not possible they must raise a field error.
Input Coercion:
[...] input value should be coerced to ID as appropriate for the ID formats a given GraphQL server expects. Any other input value, [..], must raise a query error indicating an incorrect type.
Given current ID
implementation, it is not possible to implement the coerce logic. Neither for input, nor the output side. It is also not possible to give an error on the input or output side, when coercion to the ID format expected is not possible. This must be done in the resolver itself, over and over again.
My proposal is to allow for custom coercion logic. For example using an interface, like the following:
interface CoerceID
{
/**
* @var string|int $id
* @return mixed internal ID type
*/
public function fromInput($id);
/**
* @param ValueNode $id
* @return mixed internal ID type
*/
public function fromInputLiteral(ValueNode $id);
/**
* @param mixed $id internal ID type
* @return string
*/
public function toOutput($id): string;
}
Making it BC should be possible, by having the current behavior as a default implementation. The library user should have the ability to provide a custom implementation and for example produce type error (on the input side) or field error (on the output side), when coercion was not possible.
The interfaces accepts string
and int
on the input side, and expects string
on the output side, as specified in spec. The internal server type is up to the library user.
See https://github.com/webonyx/graphql-php/issues/401 on how to override internal types
I missed that one @vladar , you was not against override of internal types?
@vladar
If I might quote you:
But note that this is just an escape hatch until we find a better way to do this.
And you are right. I do not think overriding any internal type would make sense, when they are strictly defined. ID is an exclusion here. So I checked the references issues (where you commented) and found they all actually just want to work with ID coercion!
- https://github.com/webonyx/graphql-php/issues/353
- https://github.com/webonyx/graphql-php/issues/301#issuecomment-403223102
So this is why I propose to not override the internal types, but have the ability to specify ID coercion logic.
That's why it is not quite documented %) If you are ready to tackle this and prepare a PR - I will be happy to accept it!