graphql-php icon indicating copy to clipboard operation
graphql-php copied to clipboard

Polymorphic input types

Open oojacoboo opened this issue 5 years ago • 10 comments

I'd like to go ahead and present this RFC for implementation, possibly early as it looks to have full support. Or, at the least, I'd like to get the discussion and ideas flowing for implementation in the future.

https://github.com/graphql/graphql-spec/blob/master/rfcs/InputUnion.md

This is particularly of interest in cases where you have an update mutation that has optional relational inputs. In this case, you have to support creating and updating for the relation. It's also the case for one:many relationships, if you wish to update relations within a parent mutation.

There are a number of other use cases that are also important. The above use case is one that we're finding to be very common and a continual frustration point with the API/schema.

oojacoboo avatar Feb 10 '20 16:02 oojacoboo

This implementation would be very useful for API Platform (related issues: https://github.com/api-platform/core/issues/1964, https://github.com/api-platform/core/issues/3258). Maybe it would be a way to enforce this long-awaited feature.

alanpoulain avatar Apr 21 '20 14:04 alanpoulain

We'll add it but it has to become a part of the spec first and implemented in the reference implementation (graphql-js).

vladar avatar Jun 08 '20 17:06 vladar

It's worth noting that since this issue was created, the RFC has gone on a complete tangent from the original "accepted" solution. Instead of introducing a new directive called @oneOf that's only valid on input objects, they've decided to introduce a new syntax type prefix called tagged that functionally does the same thing (but is not backwards compatible and is unclear what it does just based on the name).

In my projects I've decided to embrace the @oneOf directive, since I can implement it locally without waiting for a library or syntax update, and ignore the concept of tagged since it's not likely to get into the official Spec for possibly another year or two.

zimzat avatar Nov 11 '20 15:11 zimzat

The current rfc i could find on this is https://github.com/graphql/graphql-spec/pull/825 which moves back to a directive approach using oneOf instead of a new tagged type.

aszenz avatar Jun 08 '21 05:06 aszenz

@zimzat did you make a custom directive of @oneOf that you can share?

Roensby avatar Nov 08 '22 09:11 Roensby

@Roensby The implementation was limited to the directive declaration and a helper method to validate. I didn't build it into the library as an input validation rule because we only had half a dozen places it was used.

directive @oneOf on INPUT_OBJECT
    private function validateOneOf(array $args): void
    {
        if (count($args) !== 1) {
            throw new RequestError('@oneOf requires only one property to be set');
        }
    }

zimzat avatar Nov 11 '22 14:11 zimzat

ICYMI this got merged into graphql-js three weeks ago https://github.com/graphql/graphql-js/pull/3513

justlevine avatar Jul 16 '23 23:07 justlevine

I am not planning to work on this myself just now, but will happily accept pull requests that implement @oneOf like https://github.com/graphql/graphql-js/pull/3513. Please also incorporate https://github.com/graphql/graphql-js/pull/3937.

spawnia avatar Jul 17 '23 11:07 spawnia