1
1 Comment

GraphQL: What is the best practice for updating arrays of objects in a mutation?

I have a form that I can update a whole set of lets say recipes at once. The user should be able to cancel after editing and discard what they have filled out. When the user is done, they should be able to save which would fire off the update mutation. I will give two mutations in which I attempt to handle this. I would like to know the best practice when handling nested lists of objects in a mutation in regards to create, update, and delete?

Option 1:

mutation updateRecipesSet($id: Long!, $input: ContactsInput!) {
  updateRecipeSet(id: $id, input: {
    id: 123,
    name: "Desserts",
    recipes: [
      {
        id: 456,
        name: "Chocolate Chip Cookies",
        ingredients: [
          {
            id: 789,
            name: "Flour",
            amount: "1 cup"
          },
          {
            id: 101112,
            name: "Sugar",
            amount: "1 cup"
          },
          ...
        ]
      },
      {
        id: 131415,
        name: "Apple Pie",
        ingredients: [
          {
            id: 161718,
            name: "Apples",
            amount: "4"
          },
          {
            id: 192021,
            name: "Cinnamon",
            amount: "1 tbsp"
          },
          ...
        ]
      },
      ...
    ]
  }) {
    id
  }
}

Option 2:

mutation updateRecipesSet($id: Long!, $input: ContactsInput!) {
  updateRecipeSet(id: $id, input: {
    id: 123,
    name: "Desserts",
    recipes: {
      createRecipes: [
        {
          id: 152535,
          name: "Chocolate Cake",
          ingredients: [
            {
              id: 162636,
              name: "Eggs",
              amount: "2"
            },
            {
              id: 101112,
              name: "Flour",
              amount: "1 cup"
            },
            ...
          ]
        }
      ],
      updateRecipes: [
        {
          id: 456,
          name: "Chocolate Chip Cookies",
          ingredients: [
            {
              id: 789,
              name: "Flour",
              amount: "1 cup"
            },
            {
              id: 101112,
              name: "Sugar",
              amount: "1 cup"
            },
            ...
          ]
        },
        {
          id: 131415,
          name: "Apple Pie",
          ingredients: [
            {
              id: 161718,
              name: "Apples",
              amount: "4"
            },
            {
              id: 192021,
              name: "Cinnamon",
              amount: "1 tbsp"
            },
            ...
          ]
        },
        ...
      ],
      deleteRecipeIds: [222324, 252627]
    }
  }) {
    id
  }
}

Option 1 is simple. Whatever your object looks like is persisted to the backend and then the database. But it makes several assumptions that it I don't include an already existing item in the array it should be deleted and that I pass in an object without an id I want to create a new item. Option 2 is an attempt to resolve this however it makes the front-end logic more complex.

Should this logic even live in the front-end, or does this logic belong in the backend? Are those assumptions bad and what is the best practice to handle this scenario?

posted to Icon for group Developers
Developers
on April 6, 2020
  1. 1

    Dealing with exactly same design dilemma, I use Formik on FE to handle the array CRUD with nested objects having a id?: string property which corresponds to existing object in database. BE will have logic to compare ids and make appropriate upsert/delete on BE.

    I don't see any easy way out here but I like having as much logic as possible on BE.

    Would love to see ideas of easier patterns.

  2. 1

    This comment was deleted 6 years ago.

Trending on Indie Hackers
I shipped 3 features this weekend based entirely on community feedback. Here's what I built and why. User Avatar 152 comments I'm a lawyer who launched an AI contract tool on Product Hunt today — here's what building it as a non-technical founder actually felt like User Avatar 133 comments Finally reached 100 users in just 12 days 🚀 User Avatar 125 comments 👉 The most expensive contract mistakes don’t feel risky User Avatar 37 comments “This contract looked normal - until it didn’t” User Avatar 32 comments I realized showing problems isn’t enough — so I built this User Avatar 32 comments