Resolve multiple federated entities in a single entityResolve call #1709
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Entity resolver functions can only process one entity at a time. But often we want to resolve all the entities at once so that we can optimize things like database calls. And to do that you need to add you'd need to add batching with abstractions like dataloadgen or batchloader. The drawback here is that the resolver code (the domain logic) gets more complex to implement, test, and debug.
An alternative is to have entity resolvers that can process all the representations in a single call so that domain logic can have access to all the representations up front, which is what Im adding in this PR.
There are a few moving pieces here:
directive @entityResolver(multi: Boolean) on OBJECT
.type MultiHello @key(fields: "name") @entityResolver(multi: true)
Please note that this is very specific to federation and entity resolvers. This does not add support for resolving fields in an entity.
Some of the implementation details worth noting. In order to efficiently process batches of entities, I group them by type so that we can process groups of entities at the same time. The resolution of groups of entities run concurrently in Go routines. If there is only one type, then that's just processed without concurrency. Entities that don't have multiget enabled will still continue to resolve concurrently with Go routines, and entities that have multiget enabled just get the entire list of representations.
The list of representations that are passed to entity resolvers are strongly types, and the type is generated for you.
There are lots of new tests to ensure that there are no regressions and that the new functionality still functions as expected. To test:
plugin/federation
go run github.com/99designs/gqlgen --config testdata/entityresolver/gqlgen.yml
go test ./...
. Verify they all pass.You can look at the federated code in
plugin/federation/testdata/entityresolver/gederated/federation.go
Describe your PR and link to any relevant issues.
I have:
#1686