🔄 REST vs GraphQL

Hai kiến trúc API phổ biến — endpoints vs queries

🔵 REST

Nhiều endpoints, mỗi resource 1 URL. HTTP methods (GET, POST, PUT, DELETE). Stateless.

🩷 GraphQL

Một endpoint duy nhất, client query đúng data cần. Giải quyết over/under-fetching.

1. REST API

# REST: Mỗi resource = 1 endpoint
GET    /api/users          → Danh sách users
GET    /api/users/123      → User 123
POST   /api/users          → Tạo user mới
PUT    /api/users/123      → Cập nhật user 123
DELETE /api/users/123      → Xóa user 123
GET    /api/users/123/orders → Orders của user 123

Vấn đề Over-fetching: Client cần tên user nhưng API trả về TẤT CẢ fields:

// GET /api/users/123
// Response: trả về TẤT CẢ, dù client chỉ cần name
{
    "id": 123,
    "name": "Nguyễn Văn A",     // ← cần
    "email": "a@example.com",   // ← không cần
    "phone": "0901234567",      // ← không cần
    "address": { ... },         // ← không cần
    "avatar": "...",            // ← không cần
    "created_at": "..."         // ← không cần
}
// → Over-fetching: nhận quá nhiều data

Vấn đề Under-fetching: Cần gọi NHIỀU requests để lấy đủ data:

// Trang profile cần: user + orders + friends
// → 3 requests riêng biệt (Under-fetching)
const user = await fetch('/api/users/123');
const orders = await fetch('/api/users/123/orders');
const friends = await fetch('/api/users/123/friends');

2. GraphQL

# GraphQL: 1 endpoint, client chọn đúng data cần
# POST /graphql

query {
  user(id: 123) {
    name           # ← chỉ lấy name
    orders {       # ← lấy orders IN CÙNG REQUEST
      id
      total
      status
    }
    friends(limit: 5) {
      name
      avatar
    }
  }
}

# → 1 request duy nhất, nhận đúng data cần!
// GraphQL Server (Apollo Server)
const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
    orders: [Order!]!
    friends: [User!]!
  }

  type Order {
    id: ID!
    total: Float!
    status: String!
  }

  type Query {
    user(id: ID!): User
    users: [User!]!
  }
`;

const resolvers = {
  Query: {
    user: (_, { id }) => getUserById(id),
  },
  User: {
    orders: (user) => getOrdersByUserId(user.id),
    friends: (user) => getFriendsByUserId(user.id),
  },
};

3. Bảng So Sánh

Tiêu chí 🔵 REST 🩷 GraphQL
Endpoints Nhiều (1 per resource) Một duy nhất (/graphql)
Data fetching Server quyết định response Client chọn fields cần
Over-fetching Thường xảy ra Không (client chọn chính xác)
Under-fetching Cần nhiều requests 1 request lấy mọi thứ
Caching HTTP caching (dễ) Phức tạp hơn (cần Apollo Cache)
Versioning /api/v1, /api/v2 Không cần (thêm fields mới)
Learning curve Thấp Cao hơn
Dùng bởi Đa số companies Facebook, GitHub, Shopify

4. Khi Nào Chọn?

Chọn REST khi:
• API đơn giản, CRUD cơ bản
• Cần HTTP caching mạnh
• Public API cho third-party
• Team chưa quen GraphQL

Chọn GraphQL khi:
• Frontend phức tạp, nhiều views khác nhau
• Mobile app (tiết kiệm bandwidth)
• Microservices gateway (aggregate data)
• Data relationships phức tạp