惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
阮一峰的网络日志
阮一峰的网络日志
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
博客园 - 叶小钗
Hugging Face - Blog
Hugging Face - Blog
博客园 - 司徒正美
Last Week in AI
Last Week in AI
罗磊的独立博客
量子位
Jina AI
Jina AI
T
Tailwind CSS Blog
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
美团技术团队
雷峰网
雷峰网
爱范儿
爱范儿
S
SegmentFault 最新的问题
小众软件
小众软件
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
GraphQL là gì — Tại sao nên dùng cho Social App?
JackTT · 2026-05-21 · via DEV Community

JackTT

GraphQL là gì — Tại sao nên dùng cho Social App?


1. GraphQL là gì?

GraphQL là ngôn ngữ truy vấn cho API, do Facebook phát triển năm 2015. Thay vì server quyết định bạn nhận được gì, client tự chỉ định chính xác dữ liệu mình cần.

So sánh nhanh với REST

REST GraphQL
Endpoint Nhiều (/users, /posts...) Chỉ 1 (/graphql)
Dữ liệu trả về Fixed, server quyết định Linh hoạt, client quyết định
Over-fetching Thường xuyên Không bao giờ
Under-fetching Phải gọi nhiều request Lấy 1 lần được hết

3 khái niệm cốt lõi

  • Query — đọc dữ liệu (như GET)
  • Mutation — thay đổi dữ liệu (như POST/PUT/DELETE)
  • Subscription — lắng nghe realtime (như WebSocket)

2. Tại sao GraphQL phù hợp với Social App?

2.1 Một request — render cả trang

Feed social cần render cùng lúc: avatar, tên user, ảnh post, số like, top comment...

REST: 4–5 request tuần tự hoặc song song

GET /feed
GET /users/:id
GET /posts/:id/likes
GET /posts/:id/comments

Enter fullscreen mode Exit fullscreen mode

GraphQL: 1 request duy nhất, server tự resolve

query Feed {
  feed {
    author { avatar name isFollowing }
    content images
    likes { count isLikedByMe }
    topComments { text author { name } }
  }
}

Enter fullscreen mode Exit fullscreen mode

→ Giảm latency, giảm round-trip, render nhanh hơn rõ rệt.


2.2 Lấy đúng field cần — không thừa, không thiếu

Màn hình khác nhau → nhu cầu data khác nhau:

Màn hình Cần gì
Feed (thumbnail) name, avatar, title, likeCount
Post detail thêm fullContent, comments, shares
Profile card chỉ name, avatar, followerCount

REST trả về cùng 1 response nặng cho tất cả. GraphQL cho phép mỗi screen query đúng field nó cần — đặc biệt quan trọng với mobile, tiết kiệm bandwidth đáng kể.


2.3 Frontend không cần "gom" data từ nhiều API

REST — FE phải tự join và normalize:

const user = await getUser(id)
const posts = await getPosts(id)
const followers = await getFollowers(id)

// Rồi tự map, merge...
const profileData = mergeAndNormalize(user, posts, followers)

Enter fullscreen mode Exit fullscreen mode

GraphQL — server chịu trách nhiệm resolve mọi relationship, FE nhận về 1 object sẵn sàng dùng. Logic mapping nằm ở tầng resolver thay vì rải rác ở từng màn hình.


2.4 Caching & Batching — xử lý data lặp lại thông minh

Social feed hay có pattern: cùng 1 user xuất hiện ở nhiều post.

DataLoader pattern tự động batch + deduplicate:

Post 1 → author_id: 42  ┐
Post 2 → author_id: 17  ├─ DataLoader → 1 DB query duy nhất
Post 3 → author_id: 42  ┘   SELECT * FROM users WHERE id IN (42, 17)

Enter fullscreen mode Exit fullscreen mode

Client-side (Apollo/urql) cũng normalize cache theo object ID — user cập nhật avatar ở 1 chỗ, toàn bộ feed tự cập nhật, không cần refetch.


2.5 Self-documenting — FE tự khám phá API

GraphQL có Introspection tích hợp sẵn: schema chính là documentation. Công cụ như GraphiQL / Apollo Sandbox cho phép:

  • Autocomplete field khi gõ query
  • Xem type, mô tả của từng field ngay trong IDE
  • Không cần Postman collection hay Swagger riêng

→ FE và BE làm việc từ cùng 1 source of truth — schema file. Thêm field mới, FE thấy ngay.


3. Pain Point thực tế: /api/auth/me

Đây là ví dụ điển hình về vấn đề REST gặp phải trong production.

Hiện trạng — trả về "tất cả hoặc không có gì"

// GET /api/auth/me
{
  "id": 123456,
  "name": "Nguyễn Văn A",
  "avatar": "https://...",
  "coin": 45200,
  "rank": "GOLD",           //  aggregate loyalty_histories
  "rankProgress": 78.5,     //  tính toán nặng
  "totalEarned": 1250000,   //  SUM toàn bộ lịch sử
  "totalSpent": 890000,     //  SUM toàn bộ lịch sử
  "referralCount": 12,      //  COUNT từ bảng referrals
  "taskCompletedCount": 47, //  COUNT từ bảng task_points
  "badges": [...]           //  JOIN thêm bảng badges
}

Enter fullscreen mode Exit fullscreen mode

Mỗi lần app load → gọi /auth/me → server tính toán tất cả, dù màn hình chỉ cần hiện tên + avatar.

Phân tích chi phí thực tế

Field Chi phí server Tần suất FE dùng
name, avatar, coin Rất thấp Mọi màn hình
rank, rankProgress Nặng — aggregate loyalty_histories Chỉ màn hình Profile/Rank
totalEarned, totalSpent Nặng — SUM toàn lịch sử Chỉ màn hình Thống kê
referralCount Trung bình Chỉ màn hình Referral
taskCompletedCount Trung bình Chỉ màn hình Task
badges Nặng — multi JOIN Chỉ màn hình Profile

90% request /auth/me chỉ cần 3–4 field đầu, nhưng vẫn phải trả tiền tính toán toàn bộ.

Với GraphQL — lazy computation theo từng màn hình

App header (render mọi lúc):

query AppHeader {
  me {
    name
    avatar
    coin      # query cực nhẹ, chỉ SELECT 3 fields
  }
}

Enter fullscreen mode Exit fullscreen mode

Màn hình Profile/Rank (user chủ động vào):

query ProfileScreen {
  me {
    name avatar coin
    rank          # chỉ tính khi user thực sự mở màn hình này
    rankProgress
    badges
  }
}

Enter fullscreen mode Exit fullscreen mode

Màn hình Thống kê (vào ít nhất):

query StatsScreen {
  me {
    totalEarned       # heavy computation chỉ chạy khi cần
    totalSpent
    referralCount
    taskCompletedCount
  }
}

Enter fullscreen mode Exit fullscreen mode

Kết quả

REST hiện tại GraphQL
App header load ~150ms (tính toán full) ~8ms (chỉ SELECT 3 fields)
Profile/Rank ~150ms (dù không cần) ~120ms (lazy, chỉ khi vào)
Server load (600K users) Tính rank cho tất cả Chỉ tính khi được query

Heavy field như rank trở thành lazy resolver — không tốn tài nguyên tính toán cho 600K user mỗi khi họ mở app.