-
Notifications
You must be signed in to change notification settings - Fork 1
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
Use Struct Field Resolver instead of Method #1
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Visually inspected two passes, looks good! PR notes is good too!
6bdf423
to
bded7d4
Compare
Digged a bit into the library yesterday for learning. I tried the errors.New(fmt.Sprintf( ... )) could be replaced by a shortcut: fmt.Errorf( ... ) at We will probably use Salman's error handling library a lot, so anyways. 😃 |
@Niennienzz good suggestion - I will make the change |
Still reviewing but so far I have one suggestion. Instead of adding config.Config, why not build on the existing functional options using For example, expand // Schema represents a GraphQL schema with an optional resolver.
type Schema struct {
schema *schema.Schema
res *resolvable.Schema
maxParallelism int
tracer trace.Tracer
logger log.Logger
useFieldResolvers bool
} and add // UseFieldResovlers opts in to using struct field resolvers
func UseFieldResolvers() SchemaOpt {
return func(s *Schema) {
s.useFieldResolvers = true
}
} It's simpler, non-breaking, and the zero value, |
That's a very good suggestion. I initially explored that option. I don't remember now why I didn't continue with it. I would, however, keep I am thinking something like this:
and then
|
David, I went ahead and refactored the code as per your suggestion. It seems to be a better solution than my proposal of using a |
b74a087
to
b463cbc
Compare
graphql_test.go
Outdated
@@ -61,7 +61,7 @@ func (r *timeResolver) AddHour(args struct{ Time graphql.Time }) graphql.Time { | |||
return graphql.Time{Time: args.Time.Add(time.Hour)} | |||
} | |||
|
|||
var starwarsSchema = graphql.MustParseSchema(starwars.Schema, &starwars.Resolver{}) | |||
var starwarsSchema = graphql.MustParseSchema(starwars.Schema, &starwars.Resolver{}, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@salmana1 3rd param still needs to be removed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
// this approach avoids updating signature of many functions | ||
var useFieldResolvers bool | ||
|
||
func ApplyResolver(s *schema.Schema, resolver interface{}, useFieldRes bool) (*Schema, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of adding global state, how about adding a field to schema.Schema
? There's a pointer to it everywhere useFieldResolvers
is read: both in this func and as a member of resolvable.execBuilder
(other usages are in methods on execBuilder).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
e945f80
to
b0effb8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went through it again. I really like the way you interactively worked on this one.
b0effb8
to
de4e1e1
Compare
This fixes graph-gophers#28. Essentially, it reduces lot of boilerplate code by making use of struct field as resolvers instead of creating methods for each struct field.
Now, methods are required only when
first: Int, last: Int
etc.union
typeBy using struct fields as resolvers, one could also benefit from DRY codebase by not having a pair of a struct which look the same (one for GraphQL and one for DB)
Does this break existing API?
No. This change is completely transparent and you can continue using your existing codebase.
Can I still continue using methods as resolvers?
Yes, by default, it uses method resolvers.
How can I use struct fields as resolvers?
When invoking
graphql.ParseSchema()
orgraphql.MustParseSchema()
to parse the schema, you pass ingraphql.UseFieldResolvers()
as an argument. For an example, take a look at./example/social/server/server.go
Additional Notes
./example/social/social.go
&./example/social/server/server.go