Search code examples
node.jsreactjsgraphqlrelayjs

How to implement reference to another model in Relay Mutations on the server side?


I'm stuck with Refs in Relay Mutation and globalIdField.

So let's say that comment can have parent comment id, must have post id in props and I have a Mutation defined with following schema:

const createComment = mutationWithClientMutationId({
  name: 'CreateComment',
  description: 'Create comment of the post',
  inputFields: {
    content: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'Content of the comment',
    },
    parent: {
      type: GraphQLID,
      description: 'Parent of the comment',
    },
    post: {
      type: new GraphQLNonNull(GraphQLID),
      description: 'Post of the comment',
    },
  },
  outputFields: {
    comment: { type: commentType, resolve: comment => comment },
  },
  mutateAndGetPayload: (input, context) => (context.user
    ? Comment.create(Object.assign(input, { author: context.user._id }))
    : new Error('Only logged in user can create new comment')),
});

My comment has globalIdField, postType too. When I will query mutation from client I will use everywhere globalIds instead of real mongo _id of this objects. Is here the better way for it instead this piece in mutateAndGetPayload:

mutateAndGetPayload: (input, context) => {
  if (input.parent) input.parent = fromGlobalId(input.parent).id;
  if (input.post) input.post = fromGlobalId(input.post).id;
  // And other logic
}

It can be very convinient if I can just add globalIdField() in post, but Relay can't pass this, because field in inputFields can't have a resolver function which globalIdField has.


Solution

  • So far I can't find solution better than below:

    mutateAndGetPayload: ({ content, post, parent }, context) => {
        if (!context.user) throw new Error('Only logged in user can create new comment');
        const newComment = { author: context.user._id, content };
        if (post) newComment.post = fromGlobalId(post).id;
        if (parent) newComment.parent = fromGlobalId(parent).id;
        return Comment.create(newComment);
      },
    

    Would be so glad if somebody will provide better experience with this.