Executing code pre and post mutation graphql neo4j apollo server

I’m just getting started with GraphQL and I’ve worked mostly with featherjs to build REST APIs so far. There’s the concept of hooks to run code before or after interacting with a service. I wanted to know if there’s a way to achieve something similar in a graphql setup.

The specific stack I’m using is neo4j and graphql, express, and apollo server. Since neo4j has a graphql module, I’m not writing the general queries and mutations, just the model types.

For a concrete example, below is a basic API server. It’s put together using docker compose and has users and applications. I would like to in general be able to run arbitrary code before or after a mutation with access to the model being modified. Things like more complex validation before, or side effects after.

Those things could be here, for example, before changing the state of an application to declined, make sure that a note is added. Or after changing the state to approved, send an email to the applicant.

I’m not sure how or where to implement this kind of thing, any help is appreciated! Or also if I’m thinking about graphql wrong and there’s a better way of doing what I’m trying to do.

Thanks!

import http from 'http';
import express from 'express';
import neo4j from 'neo4j-driver';
import {Neo4jGraphQL} from '@neo4j/graphql';
import {gql, ApolloServer} from 'apollo-server-express';
import {ApolloServerPluginDrainHttpServer} from 'apollo-server-core';

const typeDefs=gql`
type User {
    email: String!
    applications: [Application!] @relationship(type: "APPLICANT", direction: OUT)
}

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

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

const {schema}=new Neo4jGraphQL({typeDefs, driver});

(async ()=>{
    const app=express();
    const server=http.createServer(app);
    const apollo=new ApolloServer({
        schema,
        plugins: [ApolloServerPluginDrainHttpServer({httpServer: server})]
    });
    await apollo.start();
    apollo.applyMiddleware({app});
    await new Promise(r=>server.listen({port: 4000}, r));
    console.log('GraphQL server listening at '+apollo.graphqlPath);
})();