You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Creating a separate ticket to follow through with the ideas raised as part of PR #103 around providing some automation / sensible defaults that would allow Java Graph Builders to more easily add the necessary federation queries and resolvers.
@setchy Thanks for the suggestions! I do think it would be nice for users to:
Have more automation around defining _entities fetchers and _Entity type resolvers.
Have some sane defaults they can activate through some simple mechanisms (e.g. inheritance).
With regards to your specific suggestions:
could the string references for any federated types (ie: "Product") be replaced by something powered by parsing any SDL types with the @extends directive
could the string references for key fields (ie: "upc") be replaced by something powered by parsing any SDL types with the @key(fields: "...") directive
For some clarifying context, a GraphQL type is an entity type if it has an @key directive, or if it implements an interface with an @key directive. Since we're given the GraphQLSchema in Federation#transform(), we can indeed use this to determine:
The GraphQL type names for all entity types.
The possible key fields for each entity type.
Note that an entity type can have multiple @key usages, and that each @key usage may specify multiple fields (additionally with nesting).
Note that a federation reference passed to the _entities resolver may additionally contain extra fields as needed by @requires.
Parsing/validating fields is going to be a bit trickier here, as the grammar for fields is basically a SelectionSet without braces with some additional limitations/validation rules, and I haven't looked into how difficult it would be for graphql-java to parse this particular symbol with a separate set of validation rules.
For the switch statements in the _entities fetcher and the _Entity type resolver, we could automate that if we let users register wirings for each entity type, e.g. looking like
publicinterfaceEntityWiring {
// The GraphQL type name of the entity.publicStringgetName();
// Resolves a federation reference to an object representing the entity type.publicObjectresolveReference(Map<String, Object> reference);
// Determines whether an object represents this specific entity type.publicbooleanisType(Objectobject);
}
We could then validate that they provide wirings for every entity type present in the schema. We could probably infer some of these automatically if the user's using a library like graphql-java-annotations where we have a well-defined correspondence between Java types and GraphQL types.
Regarding the automation of parsing of the federation reference, we could eliminate at least some boilerplate and provide type safety using something similar to JSON object mapping, where the user provides POJO classes and we validate them against the parsed @key and @requires fields. Their resolveReference() function could then take in their own class instead of having to walk Map<String, Object>. (If we can leverage code-generation tools, we could additionally generate the POJO classes for the user.)
could their be a base class that provides a default implementation of the resolveReference which each type object could extend from. In most cases it would be creating a new object, setting the @external fields with the matching @key fields and returning that new object. The type or field level resolvers could then add the necessary service layer call to populate the additional data (ie: "quantity", "inStock")
I'm not sure if we could do this exactly as written, as resolveReference() would be static and statics can't be overridden via inheritance. This also becomes trickier for the cases of multiple @keys, nested fields in @keys, and @requires fields. A potential solution that comes to mind is one where the user provides constructors that take in their POJO class, and we use reflection or annotations to detect those constructors to set up resolveReference() in an EntityWiring.
Circling back to this PR, while I believe it would be nice to provide automation and reduce boilerplate, I wouldn't say it's in scope for this PR. If you're interested in contributing to federation-jvm, you can file a GitHub issue referencing this thread and we can work through developing a more concrete proposal. 🙂
The text was updated successfully, but these errors were encountered:
setchy
changed the title
Create sane defaults that can be activated through some simple mechanism (eg: inheritance) automation for defining _entities fetchers and _Entity type resolvers@setchy Thanks for the suggestions! I do think it would be nice for users to:
Automate some sane defaults that can be activated through a simple mechanism (eg: inheritance)
Apr 21, 2021
setchy
changed the title
Automate some sane defaults that can be activated through a simple mechanism (eg: inheritance)
Provide some sensible defaults that can be activated through a simple mechanism (eg: inheritance)
Apr 21, 2021
Creating a separate ticket to follow through with the ideas raised as part of PR #103 around providing some automation / sensible defaults that would allow Java Graph Builders to more easily add the necessary federation queries and resolvers.
Some related material:
Below is a copy of the original comments
@setchy Thanks for the suggestions! I do think it would be nice for users to:
_entities
fetchers and_Entity
type resolvers.With regards to your specific suggestions:
For some clarifying context, a GraphQL type is an entity type if it has an
@key
directive, or if it implements an interface with an@key
directive. Since we're given theGraphQLSchema
inFederation#transform()
, we can indeed use this to determine:@key
usages, and that each@key
usage may specify multiple fields (additionally with nesting)._entities
resolver may additionally contain extra fields as needed by@requires
.fields
is going to be a bit trickier here, as the grammar forfields
is basically aSelectionSet
without braces with some additional limitations/validation rules, and I haven't looked into how difficult it would be forgraphql-java
to parse this particular symbol with a separate set of validation rules.For the switch statements in the
_entities
fetcher and the_Entity
type resolver, we could automate that if we let users register wirings for each entity type, e.g. looking likeWe could then validate that they provide wirings for every entity type present in the schema. We could probably infer some of these automatically if the user's using a library like
graphql-java-annotations
where we have a well-defined correspondence between Java types and GraphQL types.Regarding the automation of parsing of the federation reference, we could eliminate at least some boilerplate and provide type safety using something similar to JSON object mapping, where the user provides POJO classes and we validate them against the parsed
@key
and@requires
fields. TheirresolveReference()
function could then take in their own class instead of having to walkMap<String, Object>
. (If we can leverage code-generation tools, we could additionally generate the POJO classes for the user.)I'm not sure if we could do this exactly as written, as
resolveReference()
would be static and statics can't be overridden via inheritance. This also becomes trickier for the cases of multiple@key
s, nested fields in@key
s, and@requires
fields. A potential solution that comes to mind is one where the user provides constructors that take in their POJO class, and we use reflection or annotations to detect those constructors to set upresolveReference()
in anEntityWiring
.Circling back to this PR, while I believe it would be nice to provide automation and reduce boilerplate, I wouldn't say it's in scope for this PR. If you're interested in contributing to
federation-jvm
, you can file a GitHub issue referencing this thread and we can work through developing a more concrete proposal. 🙂Originally posted by @sachindshinde in #103 (comment)
The text was updated successfully, but these errors were encountered: