-
@yaacovCR just got really looking at schema merging for the first time... it's super impressive looking, and actually looks like a pretty comprehensive alternative to federation that might even have some advantages for us. That said, I keep coming back to the use of single-record queries here for handling the service crossover (ie: {
schema: chirpSchema,
merge: {
User: {
fieldName: 'userById',
args: (originalResult) => ({ id: originalResult.id }),
selectionSet: '{ id }',
},
},
}, How is this optimized for accessing collections of records one at a time? I assume their must be some kind of batching under the hood? Even then, it would seem like that turns into a massive query if you batch a large selectionSet over and over again for multiple single record requests... is it possible to do this crossover using a list endpoint that requests a collection of IDs from a service and returns an array (ie: Looking forward to playing around with this more. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 10 replies
-
Recent addition, also needs docs |
Beta Was this translation helpful? Give feedback.
-
We may need to customize further, see #1825 |
Beta Was this translation helpful? Give feedback.
-
Another thought here on configuring the merge schema: it'd be useful if there was an option to merge types without requiring a lookup service in both directions... this is useful for unidirectional associations where lookups would only realistically occur in a single direction. For example: usersSchema type User {
id: ID!
username: String!
posts: [Post]!
}
type Post {
id: ID!
}
type Query {
users(ids: Int): [User]!
} postsSchema type Post {
id: ID!
body: String!
user: User!
}
type User {
id: ID!
}
type Query {
posts(ids: Int): [Post]!
} gatewaySchema const gatewaySchema = stitchSchemas({
subschemas: [
{
schema: usersSchema,
merge: {
Post: true,
User: {
fieldName: 'users',
selectionSet: '{ id }',
key: ({ id }) => id,
args: (ids) => ({ ids }),
},
}
},
{
schema: postsSchema,
merge: {
Post: {
fieldName: 'posts',
selectionSet: '{ id }',
key: ({ id }) => id,
args: (ids) => ({ ids }),
},
User: true,
}
},
],
mergeTypes: true,
}); In this setup, we can use id-only models to declare associations with models in other services, which is super nice (and replaces the need for schema extensions with stitching resolvers). However, those ID-only models are really just ID stubs; they have no other data so the gateway will never have a reason to perform a lookup on them (all lookups will go to the service with additional model data). All that said, it's less than ideal that we'd need to setup a dedicated query method for an id-only stub simply to activate schema merging on the model. It'd be nice if a service could activate schema merging for a type without requiring a query for it. |
Beta Was this translation helpful? Give feedback.
-
Related to the original question, would there be a way to perform this sort of linkage going through an array method (ie: Product: {
selectionSet: '{ upc weight price }',
fieldName: '_productByUpc',
args: ({ upc, weight, price }) => ({ upc, weight, price }),
} Federation uses that idea where the stub representations would be sent to the subservice to be transformed into a list of models. Could that same sort of pattern be achieved? Maybe something like this...? Product: {
selectionSet: '{ upc weight price }',
fieldName: '_productsByUpcs',
key: ({ upc, weight, price }) => ({ upc, weight, price }),
args: (keys) => ({ representations: keys }),
} While it seems like that works for getting the data over to the subservice, how is the returned data merged in the gateway? Are all three fields used as the key? As long as one field contains a real unique ID, I suppose it wouldn't matter if the other two fields contain collisions. Is that accurate? |
Beta Was this translation helpful? Give feedback.
Recent addition, also needs docs
#1735