0
0
GraphqlHow-ToBeginner · 4 min read

How to Implement CRUD in GraphQL: Syntax and Example

To implement CRUD in GraphQL, define Query types for reading data and Mutation types for creating, updating, and deleting data. Each operation corresponds to a resolver function that handles the logic for that action.
📐

Syntax

GraphQL uses Query types to read data and Mutation types to modify data (create, update, delete). Each operation has a name, input arguments, and a return type.

  • type Query: Defines read operations.
  • type Mutation: Defines create, update, delete operations.
  • resolver functions: Implement the logic for each operation.
graphql
type Query {
  getItem(id: ID!): Item
  listItems: [Item]
}

type Mutation {
  createItem(name: String!, description: String): Item
  updateItem(id: ID!, name: String, description: String): Item
  deleteItem(id: ID!): Boolean
}

type Item {
  id: ID!
  name: String!
  description: String
}
💻

Example

This example shows a simple GraphQL schema and resolver setup for CRUD operations on an Item. It uses an in-memory array to store items.

javascript
const { ApolloServer, gql } = require('apollo-server');

const typeDefs = gql`
  type Item {
    id: ID!
    name: String!
    description: String
  }

  type Query {
    getItem(id: ID!): Item
    listItems: [Item]
  }

  type Mutation {
    createItem(name: String!, description: String): Item
    updateItem(id: ID!, name: String, description: String): Item
    deleteItem(id: ID!): Boolean
  }
`;

let items = [];
let idCounter = 1;

const resolvers = {
  Query: {
    getItem: (_, { id }) => items.find(item => item.id === id),
    listItems: () => items,
  },
  Mutation: {
    createItem: (_, { name, description }) => {
      const newItem = { id: String(idCounter++), name, description };
      items.push(newItem);
      return newItem;
    },
    updateItem: (_, { id, name, description }) => {
      const item = items.find(item => item.id === id);
      if (!item) return null;
      if (name !== undefined) item.name = name;
      if (description !== undefined) item.description = description;
      return item;
    },
    deleteItem: (_, { id }) => {
      const index = items.findIndex(item => item.id === id);
      if (index === -1) return false;
      items.splice(index, 1);
      return true;
    },
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});
Output
Server ready at http://localhost:4000/
⚠️

Common Pitfalls

Common mistakes when implementing CRUD in GraphQL include:

  • Not distinguishing between Query and Mutation types, causing confusion in client requests.
  • Forgetting to validate input arguments, which can lead to errors or inconsistent data.
  • Returning incorrect types or null without handling errors gracefully.
  • Not updating the data source properly in mutation resolvers.
graphql
/* Wrong: Using Query for data modification */
type Query {
  createItem(name: String!): Item
}

/* Right: Use Mutation for data modification */
type Mutation {
  createItem(name: String!): Item
}
📊

Quick Reference

OperationGraphQL TypePurpose
Read dataQueryFetch data without side effects
Create dataMutationAdd new data
Update dataMutationModify existing data
Delete dataMutationRemove data

Key Takeaways

Use Query for reading data and Mutation for creating, updating, and deleting data.
Define clear input arguments and return types for each CRUD operation in your schema.
Implement resolver functions to handle the logic for each operation and update your data source.
Validate inputs and handle errors gracefully to avoid runtime issues.
Avoid mixing data modification operations inside Query types.