Skip to content

Provide 'pre' and 'post' hooks on create and update #652

@GuyShane

Description

@GuyShane

Is your feature request related to a problem? Please describe.
I'd like to be able to react to changes to fields before and after they've been updated, as well as be able to access the current value of the object. For example with the below type definitions, some things I might want to do could be

  • Before a user updates their picture, save base64 information to an external file store and replace the field with a url
  • Before application state gets updated to declined, make sure a note was added
  • After application state gets updated to accepted, send an email to the user
  • Before creating an application, make sure the user is verified
const typeDefs=`
type User {
    id: ID! @id
    email: String!
    verified: Boolean! @default(value: false)
    picture: String
    applications: [Application!] @relationship(type: "APPLICANT", direction: OUT)
}

type Application {
    id: ID! @id
    user: User! @relationship(type: "APPLICANT", direction: IN)
    state: String!
    note: String
}
`;

Describe the solution you'd like
I was thinking there could be directives that allow you to attach arbitrary functions to fields or objects. Something like this

const typeDefs=`
type User {
    id: ID! @id
    email: String!
    verified: Boolean! @default(value: false)
    picture: String @pre(update: savePicture)
    applications: [Application!] @relationship(type: "APPLICANT", direction: OUT)
}

type Application @pre(create: checkVerification) {
    id: ID! @id
    user: User! @relationship(type: "APPLICANT", direction: IN)
    state: String! @pre(update: checkHasNote, value: "declined") @post(update: sendEmail, value: "accepted")
    note: String
}
`;

const driver=neo4j.driver(
    'neo4j://neo4j:7687',
    neo4j.auth.basic('neo4j', 'password')
);

const ogm=new OGM({typeDefs, driver});
const Application=ogm.model('Application');

const neoSchema=new Neo4jGraphQL({
    typeDefs,
    config: {
        hooks: {
            checkVerification, savePicture, checkHasNote, sendEmail
        }
    }
});

async function sendEmail(){
    const [application]=await Application.find({selectionSet: '{user {email}}'}); //get the existing application somehow
    await email({to: application.user.email})
}

Sorry if this is possible through other means, and if it is I'd love to know, thanks!

Describe alternatives you've considered

  • Extending generated resolvers
  • Adding directives to type fields
  • Adding directives to generated input type fields
  • Apollo server middleware

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions