-
Notifications
You must be signed in to change notification settings - Fork 254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
federation: queries for interface types require knowledge of concrete implementations #336
Comments
@lennyburdette can you change your reviews service to not know about the interface: extend type Book @key(fields: "id") {
id: ID! @external
reviews: [Review!]
}
extend type Furniture @key(fields: "id") {
id: ID! @external
reviews: [Review!]
} |
@jbaxleyiii Can I? I left the Review type alone—it still references the Product interface: type Review @key(fields: "id") {
id: ID!
body: String
author: User @provides(fields: "username")
product: Product
} |
This seems like quite a blocker for using interfaces. I'm running into the same issue where defining the type resolver for an extended interface is just impossible from the that service (the review service in the example PR above). The only work-around seems to be to reverse where the relationship is defined, but that comes with other disadvantages. |
Has this been tested in the latest version of the Gateway? |
Hi there, I am just struggling with the very same scenario.... I am just trying to reference an object that implements an interface and I'd prefer to just use that interface and only use the ID for referencing. In my case I could reluctantly even add knowledge of all implementations by listing the concrete types with The Gateway requests the original Product service via the _entities query using the interface like @jhampton I tested it with the latest Gateway (0.17.0) and I'd be very happy about any ideas or workarounds :) |
Any updates on this? |
Any updates on this? |
I've hit this same problem; this (decoupling subgraphs via interfaces) is quite a common pattern in monolithic graphs, The only workaround I can see is
which is less than ideal because it couples the dependent graph too tightly to knowledge of what types implement the interface (leading to brittleness) and it forces an extra round trip on the part of the dependent graph to do the type resolution itself (assuming its even practical for it to do this). I feel what is needed is for a subgraph to be able to return some kind of pseudo-reference to an interface instance |
Any updates on this? I'm now stuck on this very same issue |
Sorry for the very long silence on this. Fixing this is officially on the roadmap (it's the "Entity interfaces can be spread ..." bullet point) and fwiw I'm personally very keen on prioritizing this I do think it's an important part of improving separation of concerns. That said, and to be transparent, we're still in the process of prioritizing what we (at Apollo) want to do next and it's not a completely trivial issue, so a proper fix may still be a couple months away. What I can share is that the way we're currently thinking of fixing this is essentially by allowing a subgraph to "implement" an interface as an object type locally. More concretely, and to take the Product/Review example from the description of this ticket, the plan is to allow to write (only including the relevant parts): # Subgraph 'products'
interface Product @key(fields: "id") {
id: ID!
name: String
price: Int
}
type Book implements Product @key(fields: "id") {
id: ID!
name: String
price: Int
pages: Int
}
type Furniture implements Product @key(fields: "id") {
id: ID!
name: String
price: Int
weight: Int
} # Subgraph 'reviews'
type Review @key(fields: "id") {
id: ID!
body: String
author: User
product: Product
}
type Product @interfaceObject @key(fields: "id") {
id: ID!
reviews: [Review!]
} The idea being that the "reviews" subgraph don't want to have anything to do with The motivation for doing it this way is that this allows the "reviews" subgraph to both abstract I'll also note that another part of this is the support of There is more to be said on this, and I believe this proposal extends fairly naturally to more specific/complex use cases, but that can be expanded on later. In any case, the reason I'm sharing this is also to solicit early feedback. |
@pcmanus Has there been any progress here? |
Sorry again for the spotty updates. But we have starting working more concretely on the proposal I've laid out in my previous comment. And I've just created a dedicated issue for it: #2277. It's essentially still what I mention above, but I provide a bunch more details in that issue on the motivation and scope, and discuss some followups. Fwiw, I have a fair amount of it implemented, so I have to be able to share an initial patch for first look within a week or two (but obviously it'll take a bit more time to gather feedback on it and get proper testing, so still early to say when this can be expected into a release). Of course, any feedback there is welcome. |
Version:
@apollo/gateway
@0.6.6Reproduction: https://github.com/apollographql/federation-demo/compare/master...lennyburdette:interfaces?expand=1
Related issues: apollographql/apollo-server#2848
I changed the federation-demo to use an interface for the
Product
type. I could get it to work, but not without some hacks that won't work in the real world.The Reviews service has to know about
Product
implementations (Book
andFurniture
), even though it only knows aboutProduct.id
.For this query:
I see this in the query plan:
Because the Gateway fetches
__typename
, I have to implementProduct.__resolveType
(in a gross way.)This is often very hard and sometimes impossible, depending on how much information the service stores. Reviews doesn't know anything about Products other than the id, so there's no way for it to return the correct __typename.
Ideally, the query to Reviews would be:
This is less of a problem for the Inventory service because:
{ __typename: "Furniture", id: "1" }
), so Inventory can just return the given __typename.(There's also some unfortunate redundancy in Reviews and Inventory—we have to repeat __resolveReference functions for each interface implementation, but I can solve that on my side.)
The text was updated successfully, but these errors were encountered: