-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Hooks - basic plumbing #528
Conversation
3de27cb
to
ed4b85f
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.
Looking good so far!
packages/fields/Implementation.js
Outdated
@@ -82,21 +85,21 @@ class Field { | |||
* @param context {Mixed} The GraphQL Context object for the current request | |||
*/ | |||
// eslint-disable-next-line no-unused-vars |
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.
// eslint-disable-next-line no-unused-vars |
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.
👍
projects/basic/index.js
Outdated
hooks: { | ||
validateInput: async ({ resolvedData, addValidationError }) => { | ||
if (resolvedData.name === 'Barry') { | ||
addValidationError("Sorry, no Barry's allowed", { a: 1 }, { b: 2 }); |
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.
addValidationError("Sorry, no Barry's allowed", { a: 1 }, { b: 2 }); | |
addValidationError("Sorry, no Homers allowed", { a: 1 }, { b: 2 }); |
Simpsons reference.
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.
👍 😆
async _resolveDefaults(data) { | ||
const fields = this.fields.filter(field => field.getDefaultValue() !== undefined); | ||
return { | ||
...(await this._mapToFields(fields, field => field.getDefaultValue())), |
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.
This will execute getDefaultValue()
twice (once for the filter, and again for the map). Is there a way we can avoid this in case there are potentially expensive lookups performed, or the function has side effects?
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.
Yeah, I agree it's a bit icky. I've kept it like this for now just to make the field-mapping pattern clear. I'm open to changing it up once everything settles down a bit.
await this._mapToFields(fields, field => field.validateInput(args)); | ||
await this._mapToFields(fields.filter(field => field.config.hooks.validateInput), field => | ||
field.config.hooks.validateInput(args) | ||
); |
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.
🤔 Since the only output of these two functions is to call addFieldValidationError
, which pushes the given data onto fieldValidationErrors
, could we not have the validateInput
methods return errors instead?
fieldValidationErrors.push(
...(await Promise.all(fields.map(field => field.validateInput(args))))
);
Similarly for the other functions below.
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.
Yeah, this mechanism was as per the design in the hairy session. I'll leave a FIXME in the code for us to loop back to this and check whether this is what we really want.
ed4b85f
to
c021c4f
Compare
This PR implements the basic plumbing for the mutation hooks. It puts in place field type hooks and custom user hooks for fields and lists.
This PR should be considered a WIP for the full hook implementation and should not be used in production (unless you're extremely brave!)
The following things still need to be completed in future PRs:
after...()
hooks (Hooks - nested afterChange/afterDelete #533). These hooks should not be executed until all nested mutations have been completed. This will require a separate change to how we pass things through to nested mutations.