提示:本网站现在为维护调试状态

GraphQL vs REST:從 7 個維度深度對比

Choyeon
Choyeon
2026年9月19日 1 分鐘閱讀 403 閱讀
710 字 2,123 字元 更新於 2026年11月8日
GraphQL vs REST:從 7 個維度深度對比
目錄

GraphQL vs REST:从 7 个维度深度对比

GraphQL 常被宣传为 REST 的终结者,但实际两者各有适合场景。盲目选择 GraphQL 会带来 N+1 查询、复杂度爆炸、缓存失效等坑;只用 REST 又有过取/欠取问题。理性对比再做选择。

典型架构与复杂度防护

GraphQL 单端点接收查询,前端声明式指定字段结构,解决 REST 常见的 20 个接口拼数据或大接口返回 80% 不用字段的问题。但必须在网关层加上查询复杂度分析、字段级权限、深度限制。

import express, { Request, Response } from "express";
import { graphqlHTTP } from "express-graphql";
import { buildSchema, parse, visit, Kind } from "graphql";

const app = express();
app.use(express.json());

const schema = buildSchema(`
  type User { id: ID!; username: String!; orders(limit: Int = 10): [Order!]! }
  type Order { id: ID!; total: Float!; items(limit: Int = 20): [OrderItem!]! }
  type OrderItem { productId: ID!; qty: Int!; price: Float! }
  type Query { user(id: ID!): User; users(limit: Int = 20): [User!]! }
  schema { query: Query }
`);

class ComplexityGuard {
    private costs: Record<string, number> = { orders: 5, items: 2, users: 10 };
    private readonly MAX = 150;
    analyze(query: string): { total: number; exceeded: boolean } {
        const doc = parse(query); let total = 1;
        visit(doc, {
            Field: (node) => {
                const base = this.costs[node.name.value] || 1;
                const args = Object.fromEntries((node.arguments || []).map(a => [a.name.value, (a.value as any).value]));
                const mult = args.limit ? Math.ceil(Number(args.limit) / 10) : 1;
                total += base * mult;
            },
        });
        return { total, exceeded: total > this.MAX };
    }
}

const root = {
    user: ({ id }: { id: string }) => ({
        id, username: `u${id}`,
        orders: ({ limit = 10 }: any) => Array.from({ length: limit }, (_, i) => ({
            id: `o${i}`, total: 99.5 + i,
            items: ({ limit = 20 }: any) => Array.from({ length: limit }, (_, k) => ({ productId: `p${k}`, qty: k + 1, price: 9.9 })),
        })),
    }),
    users: ({ limit = 20 }: any) => Array.from({ length: limit }, (_, i) => root.user({ id: String(i + 1) })),
};

const guard = new ComplexityGuard();
app.get("/rest/users/:id", (req: Request, res: Response) => {
    res.json({ data: { id: req.params.id, username: `u${req.params.id}` }, _links: { orders: { href: `/rest/users/${req.params.id}/orders` } } });
});
app.use("/graphql", (req: Request, res: Response, next) => {
    const q = (req.body?.query) || (req.query.query as string) || "";
    const r = guard.analyze(q);
    if (r.exceeded) return res.status(400).json({ error: `Complexity ${r.total} exceeds cap 150` });
    res.setHeader("X-GraphQL-Complexity", String(r.total));
    next();
}, graphqlHTTP({ schema, rootValue: root, graphiql: process.env.NODE_ENV !== "production" }));

app.listen(3000, () => console.log("[compare] REST+GraphQL on :3000"));

七大维度横向对比

对比维度 REST (JSON:API风格) GraphQL 胜者
网络传输效率 多请求过取欠取 单请求精确字段POST不利CDN 简单REST赢/复杂视图GraphQL赢
前端开发体验 新字段等后端加接口 自助取字段+内省生成类型 GraphQL
后端演进成本 版本化管理/v1/v2 字段弃用平滑但resolver复杂度涨 REST
HTTP缓存 天然支持Get请求 需持久化查询ID+自定义层 REST
类型安全 需OpenAPI代码生成 Schema强类型+内省生成SDK GraphQL
安全风险 普通CRUD鉴权易做 深度/复杂度/批注入要防护 REST安全面更小
生态工具链 OpenAPI/Postman成熟 Apollo Studio/GraphiQL完善 打平

最佳实践

决策树:团队以 BFF 形态存在且前端迭代快 → GraphQL;微服务间调用或纯资源 CRUD → REST;混合架构:BFF 用 GraphQL 组合多个 REST 微服务是目前大厂主流方案。

X微博Telegram

本文作者

投票

你最希望 Rosetta 优先加入哪项功能?

社区投票(演示数据,可后台删除)

留言 (6)

0 / 3000
测试小瓢虫
测试小瓢虫2026年9月11日

好文!但是我觉得第三部分那个消息队列选型对比表有点偏向 Kafka 了,RocketMQ 在事务消息这块其实优势挺明显的。

自由撰稿人阿秋
自由撰稿人阿秋qiuwrites.blog2026年9月11日

建议加一下关于幂等性的讨论,现在的分布式系统里这个真的太重要了,很多坑都是没处理好幂等导致的。

东京留学僧
东京留学僧2026年9月11日

补充一点:实际使用中如果遇到 MySQL 的 8 小时超时问题,可以在连接串里加 autoReconnect=true 参数,虽然官方不推荐但挺好用的。

机器学习萌新
机器学习萌新2026年9月11日

有个小问题:你文中用的是 @Async 注解,这个默认用的是 SimpleAsyncTaskExecutor,生产环境是不是最好手动配一个线程池?

奶茶味程序媛
奶茶味程序媛2026年9月11日

代码示例里那个 SQL 查询是不是应该加个 LIMIT?不然数据量大的时候全表扫描会很慢哦。

咖啡与代码
咖啡与代码2026年9月10日

受益匪浅,感谢大佬分享!

相關文章

JWT 認證安全最佳實踐 + OAuth2 vs SAML

JWT 認證安全最佳實踐 + OAuth2 vs SAML

系統性歸納 JWT 常見安全漏洞防護:算法混淆攻擊(none/RS256→HS256)、密鑰爆破、KID注入、重放攻擊防禦,再從多個維度對比 OAuth2(授權碼+PKCE)、OIDC、SAML 2.0 三種主流認證協議選型。

1 分鐘閱讀
Prompt Engineering 入門:Few-Shot + CoT + 結構化輸出

Prompt Engineering 入門:Few-Shot + CoT + 結構化輸出

系統入門 Prompt Engineering 三大核心技術:Few-Shot 示例學習注入專業領域風格、Chain-of-Thought (CoT) 思維鏈引導複雜推理、JSON Schema 強制結構化輸出對接下游系統。附真實 prompt 模板和避坑指南。

1 分鐘閱讀
CQRS + Event Sourcing 架構模式解析

CQRS + Event Sourcing 架構模式解析

透徹解析兩種高複雜度分布式架構模式:CQRS 讀寫模型分離實現查詢極致性能、Event Sourcing 以事件作為唯一真相源實現全量審計與時間回溯,討論一致性/快照/冪等難點與反模式。

1 分鐘閱讀
快速上手 FastAPI - 構建高性能 REST API

快速上手 FastAPI - 構建高性能 REST API

FastAPI 是現代 Python Web 框架中的佼佼者,基於類型提示自動生成文檔、支持異步操作、性能媲美 Node.js。本文將通過實戰項目帶你從零構建一個完整的 CRUD API,涵蓋路由定義、請求驗證、依賴注入、數據庫集成等核心特性,讓你在 30 分鐘內掌握 FastAPI 的精髓。

這篇文章需要存取密碼 4 分鐘閱讀
Astro 靜態站點深度:群島架構 & 內容集合

Astro 靜態站點深度:群島架構 & 內容集合

深入理解 Astro 核心創新:群島架構實現最小化 JS 注入,僅交互元件按需水合;內容集合提供類型安全的 Markdown/MDX 管理,構建零 JS 的高性能靜態站點。

1 分鐘閱讀
測試金字塔:單元/整合/E2E 測試比例與落地

測試金字塔:單元/整合/E2E 測試比例與落地

系統解析測試金字塔架構:從底層單元測試(大量快速、Mock 隔離依賴)、中層整合測試(服務/數據庫/消息協作真實交互)、頂層 E2E 測試(真實用戶路徑少量精測)的推薦比例 70% / 20% / 10%,附項目覆蓋率指標與落地實踐。

1 分鐘閱讀