Building a React CRUD Application With a REST API and GraphQL

Compare building a modern React CRUD application with REST versus GraphQL. Understand trade-offs, query shapes, state mutations, and implementation patterns.

NK
Nilesh Kumar
Creator of Playground API
Building a React CRUD Application With a REST API and GraphQL

Building a React CRUD Application With a REST API and GraphQL

Suggested URL Slug: react-crud-rest-and-graphql

Primary Keyword: React REST GraphQL API

Secondary Keywords: REST vs GraphQL React, GraphQL CRUD tutorial, REST API frontend, GraphQL sandbox React

Meta Description: Compare building a modern React CRUD application with REST versus GraphQL. Understand trade-offs, query shapes, state mutations, and implementation patterns.

Suggested Dev.to Tags: #graphql, #react, #javascript, #webdev


The debate between REST and GraphQL is one of the most enduring conversations in frontend engineering.

Some developers love the simplicity, caching, and predictable HTTP status codes of REST. Others swear by GraphQL’s ability to fetch deeply nested relational data in a single round-trip without over-fetching or under-fetching.

Instead of arguing theoretically, let's explore how to build and test the exact same React CRUD feature using both approaches against a unified backend sandbox.


The Scenario: A User Profile with Posts and Comments

Imagine we are building a user profile screen that needs to display:

  1. User details (name, email, company)
  2. The user's published blog posts
  3. The latest comments on each post

Let's look at how REST and GraphQL approach this data requirement.


Approach 1: The REST Workflow

In standard REST architecture, resources are organized around distinct URL endpoints.

Fetching Data in REST:

To get the user and their related posts and comments, a REST client typically executes sequential or parallel HTTP GET requests:

javascript
1. GET /api/v1/users/1 ──► Fetches User profile
2. GET /api/v1/users/1/posts ──► Fetches Users posts
3. GET /api/v1/posts/10/comments ──► Fetches Comments for Post 10

The Advantage: Simple, intuitive, leverages standard browser and CDN caching, uses native HTTP status codes (200, 404, 500).

The Friction: Multiple network roundtrips (under-fetching) or downloading unused fields (over-fetching).

React REST Code Example:

jsx
1
// Fetching with REST
2
async function loadUserDataREST(userId) {
3
const [userRes, postsRes] = await Promise.all([
4
fetch(https://playground.nileslabs.com/api/v1/users/${userId}`),
5
fetch(https://playground.nileslabs.com/api/v1/users/${userId}/posts?_limit=3`)
6
]);
7
8
const user = await userRes.json();
9
const posts = await postsRes.json();
10
return { user, posts };
11
}

Approach 2: The GraphQL Workflow

In GraphQL, client applications query a single endpoint (/api/v1/graphql) using a declarative query language that requests only the exact fields needed.

Fetching Data in GraphQL:

With GraphQL, the entire nested data graph is retrieved in a single POST request:

graphql
1
query GetUserProfile($userId: ID!) {
2
user(id: $userId) {
3
name
4
email
5
company {
6
name
7
}
8
posts {
9
id
10
title
11
comments {
12
id
13
name
14
body
15
}
16
}
17
}
18
}

The Advantage: Zero over-fetching, single network roundtrip, strictly typed schema.

The Friction: All requests are POST to /graphql, requiring specialized client libraries (Apollo Client, URQL, or custom fetchers) to handle caching and error parsing.

React GraphQL Code Example:

jsx
1
// Fetching with GraphQL
2
async function loadUserDataGraphQL(userId) {
3
const query =
4
query GetUser($id: ID!) {
5
user(id: $id) {
6
name
7
email
8
company { name }
9
posts {
10
id
11
title
12
}
13
}
14
}
15
;
16
17
const response = await fetch('https://playground.nileslabs.com/api/v1/graphql', {
18
method: 'POST',
19
headers: { 'Content-Type': 'application/json' },
20
body: JSON.stringify({
21
query,
22
variables: { id: userId }
23
})
24
});
25
26
const { data, errors } = await response.json();
27
if (errors) throw new Error(errors[0].message);
28
return data.user;
29
}

Comparing CRUD Mutations: REST vs. GraphQL

Let's compare creating a new post:

REST Mutation (POST /api/v1/posts):

javascript
1
const res = await fetch('https://playground.nileslabs.com/api/v1/posts', {
2
method: 'POST',
3
headers: { 'Content-Type': 'application/json' },
4
body: JSON.stringify({
5
title: 'New Post via REST',
6
body: 'Content...',
7
user_id: 1
8
})
9
});
10
const createdPost = await res.json();

GraphQL Mutation (mutation CreatePost):

javascript
1
const mutation =
2
mutation AddPost($title: String!, $body: String!, $user_id: ID!) {
3
createPost(title: $title, body: $body, user_id: $user_id) {
4
id
5
title
6
body
7
user {
8
name
9
}
10
}
11
}
12
;
13
14
const res = await fetch('https://playground.nileslabs.com/api/v1/graphql', {
15
method: 'POST',
16
headers: { 'Content-Type': 'application/json' },
17
body: JSON.stringify({
18
query: mutation,
19
variables: { title: 'New Post via GraphQL', body: 'Content...', user_id: 1 }
20
})
21
});
22
const { data } = await res.json();
23
const createdPost = data.createPost;

Notice the key difference: in GraphQL, you can request nested fields (like user { name }) immediately within the mutation response, eliminating follow-up queries.


When to Choose REST vs. GraphQL

Decision FactorChoose RESTChoose GraphQL
Project ComplexitySimple to moderate CRUD appsComplex apps with deeply nested relations
Caching RequirementsHeavy reliance on HTTP/CDN cachingClient-side normalized caching (Apollo / Urql)
Bandwidth SensitivityStandard web applicationsMobile apps where every byte counts
Learning CurveLowest (Standard browser fetch)Requires understanding schemas & queries
Tooling OverheadZero tooling requiredCode generation, schema compilation

Testing Both in a Single Sandbox

Finding a sandbox that supports both modern REST filtering and a live GraphQL gateway with mutation persistence is usually difficult.

Playground API by Niles Labs offers dual REST and GraphQL gateways over the exact same underlying dataset:

  • REST Endpoints: https://playground.nileslabs.com/api/v1/posts
  • GraphQL Endpoint: https://playground.nileslabs.com/api/v1/graphql
  • Interactive GraphiQL IDE: Visit https://playground.nileslabs.com/api/v1/graphql in your browser to inspect the full schema, types, and documentation interactively.

Any record created via GraphQL is instantly accessible via REST GET /posts, and vice versa.


Conclusion

Neither REST nor GraphQL is universally "better"—they are tools tailored for different architectural priorities. By testing both approaches against a unified, stateful sandbox, you can make informed decisions based on concrete code and real network performance rather than internet dogma.

Compare REST and GraphQL hands-on with Playground API by Niles Labs.

Tags:#graphql#react#javascript#webdev

Try Playground API in Your Own App

Stateful mock REST & GraphQL API with private sandbox overlays.