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
AI runs 70% of my distribution. The exact stack. User Avatar 68 comments Show IH: I'm building a lead gen + CRM tool for web designers targeting local businesses without websites — starting with Spain User Avatar 66 comments I built a URL indexing SaaS in 40 days — here's the honest story User Avatar 56 comments I'm a solo founder. It took me 9 months and at least 3 stack rewrites to ship my SaaS. User Avatar 54 comments After 4 landing page rewrites, I finally figured out why my analytics SaaS wasn't converting User Avatar 21 comments We witnessed a sharp spike in our traffic. So much happiness after a long time. User Avatar 15 comments