GraphQl and REST(Representational State Transfer) are popular architecture for designing APIs to exchange data between a client and server. They achieve the same goal but use fundamentally different approaches.
We are going to learn the difference by CRUD Operations
CRUD Operations: REST vs. GraphQL
- Read Operation
| Feature | REST API | GraphQL |
| Request Method | Uses the standard GET HTTP method. | Uses a Query operations (usually sent via HTTP POST). |
| Endpoints | Multiple, resource specific URLs (endpoints) | A single endpoint (eg., /graphql) |
| Data Fetching | Client hits a URL to get a fixed payload. | Client sends a structured query specifying only the fields it needs |
| Example Scenario: Get a User and their 3 most recent Posts | Multiple Requests (Under-fetching): 1. GET /api/users/1232. GET /api/users/123/posts?limit=3 | Single Request:query { user(id: 123) { name email posts(limit: 3) { title } } } |
| Efficiency Issue | Prone to Over-fetching (receiving unneeded fields) or Under-fetching (requiring multiple trips). | Eliminates both issues by fetching exactly what’s requested in one trip. |
2. Create, Update, Delete (CRUD) Operations
These operations modify data on the server. They are conceptually similar but use different terminology and transport mechanisms.
| Operation | REST API | GraphQL |
| Create (C) | Uses POST method to a collection endpoint (e.g., POST /api/posts). | Uses a Mutation operation (e.g., mutation { createPost(...) { id title } }). |
| Update (U) | Uses PUT (full replacement) or PATCH (partial update) to a specific resource endpoint (e.g., PUT /api/posts/456). | Uses a Mutation operation (e.g., mutation { updatePost(...) { success } }). |
| Delete (D) | Uses DELETE method to a specific resource endpoint (e.g., DELETE /api/posts/456). | Uses a Mutation operation (e.g., mutation { deletePost(...) { id } }). |
| Transport | Each operation uses its own distinct HTTP method and URL. | All CUD operations are defined as Mutations and typically sent using a single HTTP POST request to the /graphql endpoint. |
| Return Data | The response body is a fixed, server-defined representation (often the created/updated resource). | The client specifies the return data in the mutation request (e.g., asking for the id and title of the created post). |
Example: Getting a User’s Name and Latest Order
Imagine a simple e-commerce application where you need to display a user’s name and the total price of their single latest order.
REST Implementation
To get all the necessary information, the client often needs to make two requests:
- Request 1 (Get User):
GET /api/users/123
// Server sends back ALL fields (over-fetching)
{
"id": 123,
"name": "Jane Doe",
"email": "jane@example.com",
"address": "123 Main St", // Unnecessary
"phone": "555-1212", // Unnecessary
"latestOrderId": 999 // Only needed for the next request
}
2. Request 2 (Get Order): GET /api/orders/999
// Server sends back ALL fields (over-fetching)
{
"id": 999,
"userId": 123,
"totalPrice": 45.99,
"status": "Shipped", // Unnecessary
"shippingDate": "2025-11-10" // Unnecessary
}
The client then combines the name from Request 1 and the totalPrice from Request 2.
GraphQL Implementation
The client makes a single request specifying exactly what it needs:
- Request (Query):
query GetUserNameAndOrder {
user(id: 123) {
name
latestOrder {
totalPrice
}
}
}
Response (Single Trip):
// Server sends back ONLY the requested fields
{
"data": {
"user": {
"name": "Jane Doe",
"latestOrder": {
"totalPrice": 45.99
}
}
}
}
This example shows why GraphQL is often preferred for complex UIs, as it reduces round trips and minimizes the amount of data transferred.