The GraphQL revolution in Shopify has made working with Metafields whole lot easier. The equivalent of "a picture speaks thousand words" in programming is a code sample. So here it goes:

Create Product with Metafields

mutation($input: ProductInput!) {
    productCreate(input: $input) {
      product {
        id
      }
      userErrors {
        field
        message
      }
    }
  }

Variables

{
  "input": {
    "title": "Awesome Product",
    "metafields": {
      "namespace": "awesome",
      "key": "someKey",
      "value": "someValue",
      "valueType": "STRING"
    }
  }
}

Add MetaField to existing Product

mutation productUpdate($input: ProductInput!) {
    productUpdate(input: $input) {
      product {
        id
      }
      userErrors {
        field
        message
      }
    }
  }

Variables

{
  input: {
    id: "gid://shopify/Product/100000000",
    metafields: [
      {
        namespace: "awesome",
        key: "someKey1",
        value: "someValue",
        valueType: "STRING"
      },
      {
        namespace: "awesome",
        key: "someKey2",
        value: "someValue",
        valueType: "STRING"
      },
      {
        namespace: "superawesome",
        key: "someKey2",
        value: "someValue",
        valueType: "STRING"
      }
    ]
  }
}

Now this is where the GraphQL API really shines. You can create new metafields and update existing ones in a single API call. So, in the above mutation. you can pass:

{
  input: {
    id: "gid://shopify/Product/100000000",
    metafields: [
      {
        namespace: "awesome",
        key: "newKey",
        value: "someValue",
        valueType: "STRING"
      },
      {
        id: "gid://shopify/Metafield/200000000",
        namespace: "awesome",
        key: "existingKey",
        value: "someValue",
        valueType: "STRING"
      }
    ]
  }
}

When this is POSTed, metafield newKey will be created and existingKey will be updated. When working with multiple metafields at once, this can simplify your API logic by a large magnitude.

Deleting Metafields

What has been created should be eventually deleted at some point (unless you're Facebook!). To delete metafields, there's a separate mutation:

mutation metafieldDelete($input: MetafieldDeleteInput!) {
  metafieldDelete(input: $input) {
    deletedId
    userErrors {
      field
      message
    }
  }
}

Variables

{
  "input": {
    "id": "<Metafield ID>"
  }
}

Happy Metafielding!

Cover Photo by Jon Tyson on Unsplash