Enhancing Your Application with GraphQL-Based CRUD Operations in React Grid
Detailed Blog page Skeleton loader
Enhancing Your Application with GraphQL-Based CRUD Operations in Syncfusion React Grid

TL;DR: Learn to use GraphQL with Syncfusion React Data Grid for efficient data management. This blog covers sorting, filtering, paging, and CRUD actions. Boost productivity with GraphQL’s single endpoint.

Introduction

Welcome to this blog post, where we will explore how to utilize GraphQL to connect data with the Syncfusion React Data Grid component. We will cover various operations such as sorting, filtering, grouping, paging, and CRUD (Create, Read, Update, Delete) actions. By the end of this blog, you will have a better understanding of how GraphQL can enhance your data management capabilities within the React Data Grid.

GraphQL

As per the official GraphQL website, GraphQL is a query language for your API and a server-side runtime for executing queries using a type system you define for your data. Unlike traditional REST APIs, GraphQL provides a flexible and efficient approach to querying and manipulating data. It separates the frontend and backend layers by enabling clients to specify the precise data requirements they need in a single request.

GraphQL vs. REST API

One significant advantage of GraphQL over traditional REST APIs is its use of a single endpoint. In a REST API, you usually have multiple endpoints for different resources, which requires sending multiple requests to retrieve related data. However, with GraphQL, clients can retrieve the required data precisely through a single endpoint. This reduces the number of network requests, minimizes the amount of data transferred, and leads to improved performance and efficiency.

One of GraphQL’s main advantages is its flexibility in data fetching. Instead of depending on predetermined endpoints with fixed data structures, GraphQL enables clients to specify the exact fields they require, allowing them to fetch only the necessary data. This feature empowers clients to optimize their queries and avoid fetching excessive or insufficient data.

Additionally, GraphQL is independent of the underlying storage or database system, serving as a layer on top of your existing code and data to maximize backend logic.

Comparison of REST API and GraphQL

REST API

GraphQL API

Multiple endpoints (GET/POST/PUT).

Single endpoint.

Supports JSON data exchange.

Supports JSON data exchange.

Can work with all types of databases.

Can work with all types of databases.

REST API

As I mentioned earlier, the REST API has multiple endpoints. Therefore, it will send individual requests to the server for each data operation.

Refer to the following image.Rest API Architecture

Example

Consider a social media application that uses REST API. In this application, we need to send individual HTTP API requests to fetch details such as user ID, posts, like count, and follower count.

Refer to the following image.Rest API example

GraphQL

GraphQL has a single endpoint and can send multiple queries in a single request, resulting in better performance compared to the REST API.

Refer to the following image.GraphQL API architecture

Example

You can easily retrieve the user ID, posts, like count, and follower count in a social media application by sending a single HTTP request using GraphQL.

Refer to the following image.GraphQL example

Fundamentals of GraphQL

To  begin with GraphQL, it is essential to understand the following:

  • Schema and types
  • Queries
  • Mutations
  • Resolvers

Schema and types

In GraphQL, APIs are organized based on types, and it is essential to define the precise type for each field based on our data structure. The Schema is a fundamental concept in GraphQL implementation, serving as the contract between the client and the server. It defines the available operations, object types, and relationships within the API.

type Order {
  OrderID: Int!
  CustomerID: String!
  Employees: [Employee]
}
 
type Employee {
  EmployeeID: Int!
  FirstName: String!
  LastName: String     // it accepts null value.
}

Query

In GraphQL, the query is used to read or fetch data from the GraphQL server. With GraphQL, clients can specify the exact data they require, reducing excessive or insufficient data and enabling efficient data retrieval. The following is an example of a basic query declaration in GraphQL.

{
Employee {
EmployeeID
FirstName
}
}

Mutation

In GraphQL, the mutation is used to perform Create, Read, Update, and Delete (CRUD) actions on the data in the GraphQL server. Mutations allow clients to modify or manipulate data by sending requests to the GraphQL server. The following is an example of a basic mutation declaration in GraphQL.

Mutation: {
// Perform Insert
createOrder: (parent, { value }, context, info) => {
return value;
}
}

Resolver

In GraphQL, a resolver is a function that helps to handle and resolve the fields in a GraphQL query. Resolvers are responsible for fetching the data from the appropriate data source and returning the requested values to the client. The following is an example of a basic resolver declaration in GraphQL.

const resolvers = {
  Query: {
    getOrders: (parent, { datamanager }, context, info) => {
      if (datamanager.search) {
        // Perform searching
      }
    }
  }
}

Syncfusion DataManager with GraphQLAdaptor

The GraphQLAdaptor in our Syncfusion DataManager enables efficient data management by performing CRUD operations and handling advanced data operations such as paging, sorting, and filtering. It achieves this by sending the required arguments to the GraphQL server, allowing for precise data retrieval based on the client’s needs.

Using the GraphQLAdaptor, you can seamlessly integrate Syncfusion components with a GraphQL backend and leverage its capabilities to manage and display data effectively. The GraphQLAdaptor abstracts away the complexities of working with GraphQL queries and mutations, making it easier to interact with the GraphQL server and fetch data in a structured manner.

Syncfusion React Data Grid

Our Syncfusion React Data Grid is a versatile control for displaying data in a tabular format. It offers a wide range of functionalities, including data binding, editing, Excel-like filtering, and selection. Additionally, It supports exporting data to Excel, CSV, and PDF formats.

Let’s explore how to bind data in our Syncfusion React Data Grid through the GraphQL server and carry out sorting, filtering, and other CRUD operations.

Required software

Configure GraphQL server

First, install the GraphQL server using the Graphpack npm package.

Then, include the following code in the package.json file to configure the GraphQL server.

package.json

{
  "name": "graphql-server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "graphpack --port 4200",
    "build": "graphpack build"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "graphpack": "^1.0.9"
  },
  "dependencies": {
    "@syncfusion/ej2-data": "^21.2.6"
  }
}

Create a database file

Next, create the database file, db.js, using JSON data in the GraphQL server.

Refer to the following code example.

export let orderData = [
  { 
    OrderID: 10248, CustomerID: 'VINET', EmployeeID: 5, OrderDate: new Date("07 12 1996 02:00:23"), 
    ShipName: 'Vins et alcools Chevalier', ShipCity: 'Reims', ShipAddress: '59 rue de l Abbaye', 
    ShipRegion: 'CJ', ShipPostalCode: '51100', ShipCountry: 'France', Freight: 32.38, Verified: !0 
  },
  { 
    OrderID: 10249, CustomerID: 'TOMSP', EmployeeID: 6, OrderDate: new Date("07 12 1996 00:03:23"), 
    ShipName: 'Toms Spezialitäten', ShipCity: 'Münster', ShipAddress: 'Luisenstr. 48', 
    ShipRegion: 'CJ', ShipPostalCode: '44087', ShipCountry: 'Germany', Freight: 11.61, Verified: !1 
  },
  { 
    OrderID: 10250, CustomerID: 'HANAR', EmployeeID: 4, OrderDate: new Date("07 12 1996 00:00:23"), 
    ShipName: 'Hanari Carnes', ShipCity: 'Rio de Janeiro', ShipAddress: 'Rua do Paço, 67', 
    ShipRegion: 'RJ', ShipPostalCode: '05454-876', ShipCountry: 'Brazil', Freight: 65.83, Verified: !0 
  },
  { 
    OrderID: 10251, CustomerID: 'VICTE', EmployeeID: 3, OrderDate: new Date(8367642e5), 
    ShipName: 'Victuailles en stock', ShipCity: 'Lyon', ShipAddress: '2, rue du Commerce', 
    ShipRegion: 'CJ', ShipPostalCode: '69004', ShipCountry: 'France', Freight: 41.34, Verified: !0 
  }
]

Create a schema definition for GraphQL

Then, create the Schema named Schema.graphql for the GraphQL server with the following code.

# Grid sort direction
input Sort {
  name: String!
  direction: String!
}
# Grid aggregates type
input Aggregate {
  field: String!
  type: String!
}
# Syncfusion DataManager query params
input DataManager {
  skip: Int
  take: Int
  sorted: [Sort]
  group: [String]
  table: String
  select: [String]
  where: String
  search: String
  requiresCounts: Boolean,
  aggregates: [Aggregate],
  params: String
}
# Grid field names
input OrderInput {
  OrderID: Int!
  CustomerID: String
  EmployeeID: Int
  ShipCity: String
  ShipCountry: String
}
type Order {
  OrderID: Int!
  CustomerID: String
  EmployeeID: Int
  ShipCity: String
  ShipCountry: String
}
# need to return type as 'result (i.e. current pager data)' and count (i.e., the total number of records in your database)
type ReturnType {
  result: [Order]
  count: Int
  aggregates: String
}
type Query {
  getOrders(datamanager: DataManager): ReturnType
}
type Mutation {
  createOrder(value: OrderInput): Order!
  updateOrder(key: Int!, keyColumn: String, value: OrderInput): Order
  deleteOrder(key: Int!, keyColumn: String, value: OrderInput): Order!
}

Create a resolver and mutation for the GraphQL server

Then, create the resolvers and mutation for the GraphQL server. I’m going to name this resolver.js.

Refer to the following code example.

const resolvers = {
  Query: {
    getOrders: (parent, { datamanager }, context, info) => {
      var ret = DataUtil.processData(datamanager, orderData);
      return ret;
    }
  },
  Mutation: {
    createOrder: (parent, { value }, context, info) => {
      const newOrder = value;
      orderData.push(newOrder);
      return newOrder;
    },
    updateOrder: (parent, { key, keyColumn, value }, context, info) => {
      let newOrder = orderData.find(order => order.OrderID === parseInt(key));
      newOrder.CustomerID = value.CustomerID;
      newOrder.EmployeeID = value.EmployeeID;
      newOrder.ShipCity = value.ShipCity;
      newOrder.ShipCountry = value.ShipCountry;
      return newOrder;
    },
    deleteOrder: (parent, { key, keyColumn, value }, context, info) => {
      const orderIndex = orderData.findIndex(order => order.OrderID === parseInt(key));
      if (orderIndex === -1) throw new Error("Order not found." + value);
      const deletedOrders = orderData.splice(orderIndex, 1);
      return deletedOrders[0];
    }
  }
};
export default resolvers;

Run the GraphQL server

Finally, run the GraphQL server using the following commands.

First, install the necessary packages:

npm install

Then, run the server:

npm run dev

Now, the server will be hosted at the URL http://localhost:4200/. We can communicate with GraphQL by assigning this URL to the dataManager.url property.

Add the Syncfusion React Data Grid component

Refer to the Getting Started with React Data Grid documentation, set up the React environment, and add the Syncfusion React Data Grid component to your app.

Data Fetching

In the sample, we have added the GraphQLAdaptor, which allows you to fetch data from the GraphQL server. You can interact with the GraphQL server by adding the query property and specifying the response format using the response.result and response.count properties.

const data = new DataManager({
    adaptor: new GraphQLAdaptor({
        query: `query getOrders($datamanager: DataManager) {
              getOrders(datamanager: $datamanager) {
                 count,
                 result{OrderID, CustomerID, EmployeeID, ShipCountry}
               }
             }`,   
        response: {
            count: 'getOrders.count',
            result: 'getOrders.result'
        },
    }),
    url: 'http://localhost:4200/'
});

Render React Grid component

Now, the above data is added to the Grid dataSource property.

<GridComponent dataSource={data} allowPaging={true} allowFiltering={true} allowSorting={true} allowGrouping={true} editSettings={{allowAdding:true, allowEditing:true, allowdeleting:true}} toolbar={["Add", "Edit", "Delete", "Update", "Cancel"]}>
 <ColumnsDirective>
  <ColumnDirective field='OrderID' headerText="Order ID" isPrimaryKey={true} width='100' textAlign="Right" />
  <ColumnDirective field='CustomerID' headerText="Customer ID" width='100' />
  <ColumnDirective field='ShipCountry' headerText="ShipCountry" width='100' />
  <ColumnDirective field='EmployeeID' headerText="Employee ID" width='100' textAlign="Right" />
 </ColumnsDirective>
 <Inject services={[Filter, Page, Sort, Group, Edit, Toolbar]} />
</GridComponent>

Also, we have enabled the Paging, Filtering, Sorting, and Grouping features in the Grid component. when sending data fetching requests, the query parameters requiresCounts, skip, take, sorted, and where details to be sent with the variables.Grid component Paging, Filtering, Sorting & Grouping features enabled with query parameters.

This is the schema for the parameters in the GraphQL server.

input DataManager {
    skip: Int
    take: Int
    sorted: [Sort]
    group: [String]
    where: String
    requiresCounts: Boolean
}
input Sort {
    name: String!
    direction: String!
}

You can get these values in the resolver method getOrders, process the data, and return the response as a result and count pair.

Query: {
  getOrders: (parent, { datamanager }, context, info) => {
    if (datamanager.sorted) {
      // Perform sorting
    }
    if (datamanager.where) {
      // Perform filtering
    }
    if (datamanager.skip && datamanager.take) {
      // Perform Paging
    }
    return { result: data, count: data.length };
  }
}

Performing CRUD operations

You can perform CRUD actions by returning the mutation inside the getMutation method based on the action.

var data = new ej.data.DataManager({
    adaptor: new ej.data.GraphQLAdaptor({
        query: `query getOrders($datamanager: DataManager) {
                getOrders(datamanager: $datamanager) {
                    count,
                    result{OrderID, CustomerID, EmployeeID, ShipCountry}
                }
            }`, 
        getMutation: function (action) {
            if (action === 'insert') {
                return `mutation Create($value: OrderInput!){
                            createOrder(value: $value){
                                OrderID, CustomerID, EmployeeID, ShipCountry
                            }}`;
            }
            if (action === 'update') {
                return `mutation Update($key: Int!, $keyColumn: String,$value: OrderInput){
                            updateOrder(key: $key, keyColumn: $keyColumn, value: $value) {
                                OrderID, CustomerID, EmployeeID, ShipCountry
                            }}`;
            } else {
                return `mutation Remove($key: Int!, $keyColumn: String, $value: OrderInput){
                        deleteOrder(key: $key, keyColumn: $keyColumn, value: $value) {
                                OrderID, CustomerID, EmployeeID, ShipCountry
                            }}`;
            }
        },
        response: {
            count: 'getOrders.count',
            result: 'getOrders.result'
        },
    }),
    url: 'http://localhost:4200/'
});

Note: Refer to the Editing in React Data Grid documentation for more details.

Run the application

To run the client application, you must install the required packages using the commands below.

npm install
npm start

Using the React Data Grid component, you can efficiently perform sorting, paging, filtering, and CRUD operations.

Refer to the following GIF image.

Performing CRUD Operation in React Data Grid using GraphQL
Performing CRUD Operation in React Data Grid using GraphQL

GitHub reference

For more details, refer to the example Performing CRUD Operation in React Data Grid using GraphQL GitHub demo.

Explore the endless possibilities with Syncfusion’s outstanding React UI components.

Conclusion

Thank you for taking the time to read! I hope you now have a clear understanding of how to use the GraphQL server in our Syncfusion React Data Grid component to bind data and perform CRUD operations in it. Since GraphQL has a single endpoint, it can save you time and significantly boost your productivity when fetching data. I encourage you to follow the steps in this blog post and share your feedback in the comments section below!

The Syncfusion DataGrid component is also available in the Blazor, ASP.NET (CoreMVC), JavaScript, AngularReactVueXamarinFlutterUWPWinFormsWPF, and WinUI platforms. Use it to build great applications!

For existing customers, the latest version of Essential Studio® is available for download from the License and Downloads page. If you are not a Syncfusion customer, try our 30-day free trial to check out our available features.

You can contact us through our support forumsupport portal, or feedback portal. We are here to help you succeed!

Related blog

Be the first to get updates

Maithiliy K

Meet the Author

Maithiliy K

Maithiliy is a Product Manager for web components at Syncfusion. She has 9 years of experience in developing software components and has started her career in Syncfusion in 2010. She is an expert in providing solutions for web products related requirements.