-
-
Notifications
You must be signed in to change notification settings - Fork 593
Question about Federation and Relay IDs #3177
-
I'm trying to federate a new strawberry service with an existing graphene service using Apollo Router. Everything was working (surprisingly) well until I through Relay into the mix.
Graphene's Relay defines the interface Node.id as type ID!, but strawberry defines it as type GlobalID!. This is causing the following error when I try to stitch the two schemas with rover:
FIELD_TYPE_MISMATCH: Type of field "Node.id" is incompatible across subgraphs: it has type "ID!" in subgraph "graphene" but type "GlobalID!" in subgraph "strawberry"
The sources for relay.types.GlobalID say:
Different from `strawberry.ID`, this ID wraps the original object ID in a string
that contains both its GraphQL type name and the ID itself, and encodes it
to a base64_ string.
So it sounds like these really are two different types, but it is unclear to me what the Federation mechanism expects or how to resolve the discrepancy, given that my code doesn't control the Node Interface in either service. Are there any more experienced Federation users out there able to give me some advice?
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 3 comments 6 replies
-
hi @dusty-phillips, I'd consider this a bug (or missing feature) on our side, I think we should allow Node to use ID! instead of GlobalID!
I'm not sure if there's a good way to work around this on the Router, maybe you could replace all usage of GlobalID with ID, but not sure if that would work well in all cases :)
Beta Was this translation helpful? Give feedback.
All reactions
-
I found https://graphql.org/learn/global-object-identification/ and while I'm not 100% clear on whether that is relay-specific, it does indeed sound like strawberry's use of GlobalID is not the expected interface. I'll dig into Rover's config and see if there's any way I can do some type rewriting on the incoming schema; otherwise I'll have to find a way to make Strawberry share that type. Thanks for the validation!
Beta Was this translation helpful? Give feedback.
All reactions
-
btw this is something we want to implement :)
Beta Was this translation helpful? Give feedback.
All reactions
-
I'll see if I have some time next week to do it :D
Beta Was this translation helpful? Give feedback.
All reactions
-
🎉 1
-
For your reference, I unblocked myself by editing relay/types.py to add this line:
ID = scalar(NewType("ID", GlobalID), serialize=str, parse_value=GlobalID.from_id)
and changing the return type of def _id from GlobalID to ID.
I have lots of reservations about this, haven't run unit tests, and am terrified of how it's going to interact with strawberry.ID, but it'll let me drive my POC forward.
Beta Was this translation helpful? Give feedback.
All reactions
-
I honestly don't think it will be helpful, but I've put my changes up here in case it saves you any time in your investigation: #3180 Feel free to ignore it!
Beta Was this translation helpful? Give feedback.
All reactions
-
The next problem I've encountered in trying to federate graphene with strawberry has to do with the relay integrations. If I try to add a connection to both graphene and strawberry, I get the following errors from Rover:
INVALID_FIELD_SHARING: Non-shareable field "PageInfo.hasNextPage" is resolved from multiple subgraphs: it is resolved from subgraphs "graphene" and "strawberry" and defined as non-shareable in subgraph "strawberry"
INVALID_FIELD_SHARING: Non-shareable field "PageInfo.hasPreviousPage" is resolved from multiple subgraphs: it is resolved from subgraphs "graphene" and "strawberry" and defined as non-shareable in subgraph "strawberry"
INVALID_FIELD_SHARING: Non-shareable field "PageInfo.startCursor" is resolved from multiple subgraphs: it is resolved from subgraphs "graphene" and "strawberry" and defined as non-shareable in subgraph "strawberry"
INVALID_FIELD_SHARING: Non-shareable field "PageInfo.endCursor" is resolved from multiple subgraphs: it is resolved from subgraphs "graphene" and "strawberry" and defined as non-shareable in subgraph "strawberry"
I expect this to be a recurring theme for common types that are defined internally by both graphene and strawberry. First Node, now PageInfo.
I haven't tested yet, but one solution is to mark the relay fields as shareable in the relay.types. However, doing so forces the relay subpackage to depend on the federation subpackage (Shareable is defined in strawberry.federation.schema_directives and it's not clear to me whether this is undesirable. I'll test it anyway and let you know what I discover.
EDIT: Trying to depend on strawberry-federation from inside relay results in a circular import, suggesting that my concerns are valid.
Beta Was this translation helpful? Give feedback.
All reactions
-
Hacked together a workaround using good ol' copy-paste. e9d1261
Beta Was this translation helpful? Give feedback.
All reactions
-
@dusty-phillips @patrick91 any updates on this? I am attempting to do the exact same thing (use federation + relay together) and running into this issue. Is forking and patching the best approach for now?
Beta Was this translation helpful? Give feedback.