Home GraphQL backend — update & delete
Post
Cancel

GraphQL backend — update & delete

In the first installment, I covered create and read operations to the Expense entity. Now let’s add few more operations ⇨ update and delete queries.

Entire source code is available in github. For intial setup read this post. As Netflix — DGS propose, start with schema and then edit the fetcher.

⌨️ Code it

Open schema.json and add these mutations. They’re not treated differently from the createExpense mutation. Whatever write operation, it is treated as mutation. Let’s update the mutations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//File: "schema.json"

type Mutation {
    createExpense(data: ExpenseInput) : Expense
    deleteExpense(id: ID): Boolean
    updateExpense(expense: UpdatedExpense): Expense
}

input UpdatedExpense {
    id: ID
    remarks: String
    amount: Int
    isIncome: Boolean
}

Corresponding query fetchers are pretty straightforward.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  
  // Deletes an expense if any and return true or false based on it.
  @DgsMutation
  fun deleteExpense(id: Int): Boolean {
      return expenses.removeIf { it.id == id }
  }

  @DgsMutation
  fun updateExpense(expense: Expense): Expense {
      // This is an upsert operation. If id already present in list
      // overwrite it / otherwise insert at 0th index
      val index = expenses.indexOfFirst { it.id == expense.id }
      if (index != -1) {
          expenses[index] = expense
      } else {
          expenses.add(0, expense)
      }
      return expense
  }

Notice that we have separate input type defined in schema for updateExpense mutation while the mutation reuses the same type?

This is because, GrpahQL expects separate entities created for input and data models. Wheras in the dataftcher, only constraint is to match the data model to schema.

🚀 Run it

I’ve listed few queries that you can run in our server.

  • Run ./gradlew bootRun to start the server
  • Open http://localhost:8080/graphiql in the browser and try these queries
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# Creates an expense with this input
mutation CreateExpense {
  createExpense(data: {remarks: "From GraphiQL", amount: 100, isIncome: true}) {
    id
    remarks
    amount
    isIncome
  }
}

# Lists all the expenses
query ListExpenses {
  expenses {
    id
    remarks
    amount
    isIncome
  }
}

# Deleting an expense
mutation DeleteItem {
  deleted: deleteExpense(id : 1)
}

# Update / insert an expense based on id
mutation UpdateItem {
  
  updateExpense(expense: {id: 2, remarks: "From GraphiQL", amount: 100, isIncome: true} ) {
    id
    remarks
    amount
    isIncome
  }
}


It is rather simple change that we did, and now we have completed CRUD operations on a simple data set. Changes are available in a single commit here.

Endnote

This is a short post, it just gives you an idea on how delete / update operations can be written using GraphQL. This whole article has only one take, that we don’t have to create UpdatedExpense class in data fetcher to run the mutation. Any data model that matches the field type and argument name, will do just fine.

In future articles in the series, I’ll explore nested objects and how effective GraphQL is when it comes to resource consumption.

This post is licensed under CC BY 4.0 by the author.