-
Notifications
You must be signed in to change notification settings - Fork 493
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
Add Custom Directive Support for Fields #543
Conversation
based on graph-gophers#446 and work by @eko
3d6f14a
to
fd885f0
Compare
I added a commit that addresses your comment. I will keep my changes in a separate commit and then we can squash the whole thing down when we are ready merge. |
1506179
to
ddc1b7a
Compare
the types package is for types only, not implementation details.
result = res.FieldByIndex(f.field.FieldIndex) | ||
// After hook directive visitor (when no error is returned from resolver) | ||
if !f.field.HasError && len(f.field.Directives) > 0 { |
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 don't think that struct resolver fields can ever produce an error but I'm not an expert. Shall we delete this, Pavel?
if !f.field.HasError && len(f.field.Directives) > 0 { | |
if len(f.field.Directives) > 0 { |
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.
Yes, struct fields cannot produce an error. It doesn't make sense to me to check for one.
@pavelnikolov thanks for the review feedback so far. I have some questions about how we should handle errors from directive visitors. Wondering if you've thought this through before. |
@rudle I think that it is fine to stop execution if we have an error in the |
I'm not opposed to adding on to this PR nor am I in a rush to have it merge it, but I don't have the time to do the requirements gathering you're describing here. What I will do as a next action is experiment with different options for how we can pass state between |
Maybe we can have a 3rd method which returns |
OK. A 3rd return value from I just did a quick code sketch of a directive implements server-side caching via a struct field set in Earlier today, I tried to find a nice way for |
above commit adds a new test case that demonstrates how to implement server-side caching. It takes the approach of adding a second return value to |
Thank you @rudle! Happy New Year! I like the 3rd return value! This makes sense to me and looks nice. {
user {
id
name
friends(first: 10, after: "opaqueCursor") {
edges {
cursor
node {
id
name
}
}
pageInfo {
hasNextPage
}
}
}
} So imagine we want to cache the friends of a user and when we open their profile get the first 10 friends from cache. The schema declaration would look like this:
The interesting thing there is the
see their "understanding cacheKey argument section". Other than that, I am happy with this PR. I have few other thoughts:
|
Hello! Happy new year. Thanks for all the feedback so far. Excited that this is maybe getting close!
Definitely agree with this. I appreciate the legwork you have already done to find some specific directives to help guide the API. The graphql-go community will no doubt have more specific feedback for this initial implementation as they try it out on their own applications. I also suspect that once this PR lands, more small contributions and improvements from the community will quickly follow. We should plan to iterate on this API and document that things are unstable.
This is supported in this PR, but in an untyped way. The 3rd argument to
This makes some sense to me but it seems hard to support. I don't know of any prior art for this type of thing within graphql-go. It seems to me that each field resolves in isolation of other fields and that walking up and down the graph isn't supported. It seems a bit related to this very old issue #17. |
Indeed it is similar issue, however, I can imagine people opening issues about it. The selected fields issue is easy to solve, but it is difficult to implement in a type-safe way without changing the existing resolver API. I don't want selected fields extraction to happen through the context if possible. Therefore, this would require some other argument to the resolvers containing information about the GraphQL request such as the selected fields and maybe some other info in future. |
} | ||
|
||
type Query { | ||
hello(full_name: String!): String! @cached(key: "notcheckedintest") |
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.
It would be cool if this key can come from the resolved entity's ID somehow. In a real-world situation we would need to use the ID of that entity or the ID of its parent, for example, the products of a category or the comments of a post. In both of these examples we need to cache by the ID of the parent entity. I wish we could somehow do that.
@rudle I added a few commits to your branch. I added an example
I believe that this code is ready to be merged. I'll probably mention in the |
I just pushed a commit which passes the |
I'm going to merge this PR the way it is. It already covers basic usage of field directives. I put a note in the readme that the directives API is potentially subject to change in future versions. You are correct that some of my ideas are outside of the scope of this PR. When in future it is possible to check selected fields in a resolver it will be introduced retrospectively into directives as well. Then potentially we will be able to access field arguments as well. That is why I stated that potentially the directives resolver API is subject to change. |
Thanks @pavelnikolov! I was just checking in on this PR and am happy to see that it's merged. I'm excited for the next steps that will make this feature more powerful, especially checking for selected fields. |
|
* Added support of custom directives Co-authored-by: Vincent Composieux <vincent.composieux@gmail.com> Co-authored-by: Sean Sorrell <me@seansorrell.org> Co-authored-by: Pavel Nikolov <pavelnikolov@users.noreply.github.com> Co-authored-by: pavelnikolov <me@pavelnikolov.net>
* Added support of custom directives Co-authored-by: Vincent Composieux <vincent.composieux@gmail.com> Co-authored-by: Sean Sorrell <me@seansorrell.org> Co-authored-by: Pavel Nikolov <pavelnikolov@users.noreply.github.com> Co-authored-by: pavelnikolov <me@pavelnikolov.net>
based on #446 and work by @eko
I intend to revive the stalled conversation from #446 with this PR. I addressed the open comments on that change.