Need clarification what webhooks are for in Dgraph

Since I quite often come across deep mutations in my applications, I recently tried to find some (more or less) solutions for it. The most simple, although not general, approach is using webhooks.

Assume the schema

interface Asset {
  id: ID!
  name: String!
  assetType: AssetType!
}

union AssetType = Internal | External

type Internal {
  id: ID!
  src: String!
}

type External {
  id: ID!
  url: String!
}

type CourseAsset implements Asset @lamdaOnMutate(add: false, update: true, delete: false) {
  id: ID!
  courseRef: Course!
  
  # from Asset
  # name: String!
  # assetType: AssetType!
}

then we can add a webhook (minified example)

const updateAssetWebhook = async ({event, graphql, dql, authHeader}) => {
  // get set from event object
  const assetType = Object.keys(event.update.setPatch.assetType)[0];
  const { id, ...set } = event.update.setPatch.assetType[assetType]

  // run mutation
  await graphql(`
    mutation Asset($id: ID!, $set: SetAssetPatch!) {
      update${assetType[0].toUpperCase()}${assetType.slice(1, -3)}Mutation(
        input: {
          filter: { id: $id }
          set: $set
        }
      )
    }
  `, {set: set})
}

self.addWebHookResolvers({
  "CourseAsset.update": updateAssetWebhook,
});

In my frontend, I’d run the following query

mutation UpdateCA {
  updateCourseAssetMutation(
    input: {
      filter: { id: "0x1" },
      set: {
        name: "Updated Asset",
        assetType: {
          internalRef: {
            id: "0x2",
            src: "path-to-new-src"
          }
        }
      }
    }
  ) {
   courseAsset {
     name
     assetType {
       ...on Internal {
         src
       }
     }
   }
}
}

This works and also my deep mutation updates the correct node without creating a new one. However, since webhooks run after the original request, the return value for, in this case, Internal is still the old one.

Therefore my question: what is the intention of webhooks? Since we have access to all that data and are allowed to run graphql and/or dql mutations, we could definitely alter data from the original mutation. Would it not be wise to only commit the original mutation after the webhook has been successfully executed? Also errors cannot be handled since the frontend will never know about them.

I 100% agree with you on this. This was the biggest oversight the original team made. They were going to make pre and post hooks, but at the last minute decided that pre hooks would slow down the mutation, closed out the issue as if completed and resolved, having only added post hooks. Nobody cared about post hooks.

All mature databases have both, unless there is an easy way to rollback data. SQL has pre, post, and instead of hooks. Ask me what neo4j has.

However, we are talking about the GraphQL layer here, so I guess we can give them some slack. :face_with_peeking_eye:

This would solve literally all my mutation issues by allowing me to write my own work around.

In any case:

J

2 Likes

Thanks @Poolshark for the detailed use case, it helps me better understand the use cases @jdgamble555 already reported to us. We will work on that. Improving Lambda use experience is identified as a topic for ‘now’. I’ll make sure engineers read your use case…

2 Likes

Why should pre-hooks be slower than post-hooks? :face_with_raised_eyebrow:

Same for me! :raised_hands:

Thanks for the feature request by the way! :pray:

Thanks! I’m also more than happy to help. With more use cases, ideas, …

2 Likes

Because you would effectively be putting middleware before the actual query. You can’t run the actual query until the middleware completes, hence slowing it down. Also worth noting that lambdas run on an entirely different server.

That being said, still 1000% worth it, as the speed of mutations don’t matter as much compared the the importance of the speed of queries.

J

3 Likes

Well, of course! That’s the entire point of having a middleware. Post-hooks should also prevent the main request to be executed before their completion (at least you should be able to trigger a rollback). Pre/post hooks just define the DB state before and after the main request.

But now I understand the logic behind performance :smile: - it’s a bit misleading from the Dgraph team here.

1 Like