Can I update fields with the @id directive?

I have tried

const dqlUpdate = await dql.mutate(
  {
    set: {
      "uid": $id,
      "email": $email,
      "role": {
        "id": $roleId
       }
      }
    },
      { 
        id: input.userId,
        email: input.email,
        roleId: input.roleId
      }
);

but I get the error that $id is not defined

You have two inputs, just input one object with exactly what you want.

{
  "uid": $input.userId
  "email": $input.email
  "role": {
    roleId: $input.roleId
  }
}

or whatever it may be…

J

Sorry, I might be mistaken here but how would I get the input parameter if I don’t pass it to dql.mutate? I could do something like

{
  "uid": `${input.userId}`
  "email": `${input.email}`
  "role": {
    roleId: `${input.roleId}`
  }
}

but unfortunately this does not work either.

Well, I gave up on this issue and now do 2 different (actually 3) different mutations. I guess this is not the way it is supposed to be but at least it works for me…

For completeness, I post my solution. Let’s assume that we have:

  • an external ID (email with @id directive)
  • an Edge Role on the parent node User with an Enum Type
  • an Edge Organisation on the parent node User as an Array of nodes

The Setup

type User {
  id: ID!
  email: String! @id
  role: Role!
  organisations: [Organisation!]!
}

type Role {
  id: ID!
  type: RoleType!
}

enum RoleType {
  "ADMIN"
  "MEMBER"
}

type Organisation {
  id: ID!
  name: String!
}

In order to update the email field with the @id directive, we need to execute a DQL mutation. I do this with

const dqlUpdate = await dql.mutate(`{
  set {
    <${input.userId}> <User.email> "${input.email}" .
  }
}`);

Since I could not find out how to update the edges of the parent node with DQL, I do this with a GraphQL mutation. Let’s start with the role field first since updating arrays is still a bit more complicated

const graphQlUpdate = await graphql(`
 mutation(
   $id: [ID!]
   $roleId: ID!
 ) {
   updateUser( input: {
     filter: { id: $id },
     set: {
       role: {
         id: $roleId
       }
     }
   }) {
     numUids
   }
 }
`, { ...input });

When updating arrays of edges (or references), we have to remove and add the references within the mutation. Since my array isn’t that large I always remove the entire array first and then add my new array. This mean I can extend the above mutation

const graphQlUpdate = await graphql(`
  mutation(
    $id: [ID!]
    $roleId: ID!
    $addOrgs: [OrganisationRef!]
    $removeOrgs: [OrganisationRef!]
  ) {
    first: updateUser( input: {
      filter: { id: $id },
      remove: { organisations: $removeOrgs },
      set: {
        role: {
          id: $roleId
        }
      }
    }) { numUids }
    second: updateUser( input: {
      filter: { id: $id },
      set: {
        organisations: $addOrgs
      }
   }) { numUids }
  }
`, { ...input });

The complete lambda would then be

async function amendUser({ args, dql, graphql }) {
  const { input } = args;
  
  const dqlUpdate = await dql.mutate(`{
    set {
      <${input.id}> <User.email> "${input.email}" .
    }
  }`);

  const graphQlUpdate = await graphql(`
    mutation(
      $id: [ID!]
      $roleId: ID!
      $addOrgs: [OrganisationRef!]
      $removeOrgs: [OrganisationRef!]
    ) {
      first: updateUser( input: {
        filter: { id: $id },
        remove: { organisations: $removeOrgs },
        set: {
          role: {
            id: $roleId
          }
        }
      }) { numUids }
      second: updateUser( input: {
        filter: { id: $id },
        set: {
          organisations: $addOrgs
        }
     }) { numUids }
   }
`, { ...input });

return { success: "Yay!" }
}

I still don’t think this is the right way of doing this but it works… Any suggestions welcome!

That is a different question entirely.

That is the same think as just $input.userId. The args are automatically passed to the lambda function like so:

async function newPost({args, dql, authHeader}) {

Either the event object in a lambda webhook, or the args object in a lambda mutation.

Here is a full example of a lambda mutation.

J

Hi! I have tried this but since I have to use Webpack (because of additional external packages) for building my Lamda Function, your example won’t compile.

But thanks for the effort! I hope that updating fields with the @id directive will be supported by graphql Mutations soon.