Back to all posts

GraphQL vs REST API


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

  1. Read Operation
FeatureREST APIGraphQL
Request MethodUses the standard GET HTTP method.Uses a Query operations (usually sent via HTTP POST).
EndpointsMultiple, resource specific URLs (endpoints)A single endpoint (eg., /graphql)
Data FetchingClient 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 PostsMultiple Requests (Under-fetching):

1. GET /api/users/123

2. GET /api/users/123/posts?limit=3
Single Request:

query { user(id: 123) { name email posts(limit: 3) { title } } }
Efficiency IssueProne 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.

OperationREST APIGraphQL
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 } }).
TransportEach 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 DataThe 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:

  1. 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:

  1. 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.