API 集成入门:REST vs GraphQL 对比与选型指南

无论你是前端开发者还是后端开发者,API 都是日常工作中不可或缺的部分。REST 多年来一直是 API 设计的标准,而 GraphQL 作为一种更灵活的新范式正在快速普及。

一、REST 基础

1.1 什么是 REST

REST(Representational State Transfer)是一种基于 HTTP 协议的 API 设计风格。核心思想是将资源抽象为 URL,通过 HTTP 方法进行操作。

# RESTful API 设计
GET    /api/users          # 获取用户列表
GET    /api/users/1        # 获取单个用户
POST   /api/users          # 创建用户
PUT    /api/users/1        # 更新用户
DELETE /api/users/1        # 删除用户

1.2 REST 请求示例

// 获取用户及其文章
const user = await fetch('/api/users/1').then(r => r.json());
const posts = await fetch('/api/users/1/posts').then(r => r.json());
const comments = await fetch('/api/posts/1/comments').then(r => r.json());

// 响应通常包含固定结构
// GET /api/users/1
{
  "id": 1,
  "name": "张三",
  "email": "[email protected]",
  "avatar": "https://..."
}

二、GraphQL 基础

2.1 什么是 GraphQL

GraphQL 是由 Facebook 开发的一种 API 查询语言。客户端可以精确指定需要的数据,不多不少。

# GraphQL 查询
query {
  user(id: 1) {
    name
    email
    posts {
      title
      comments {
        content
        author {
          name
        }
      }
    }
  }
}

2.2 GraphQL 响应

{
  "data": {
    "user": {
      "name": "张三",
      "email": "[email protected]",
      "posts": [
        {
          "title": "第一篇文章",
          "comments": [
            {
              "content": "写得好!",
              "author": {
                "name": "李四"
              }
            }
          ]
        }
      ]
    }
  }
}

三、核心差异对比

3.1 数据获取

维度 REST GraphQL
数据量 固定结构,可能过多或不足 客户端精确指定
请求次数 可能需要多次请求 一次请求获取所有数据
嵌套数据 需多次请求或自定义端点 直接在查询中嵌套

3.2 示例对比

场景:获取用户信息 + 最新的 5 篇文章 + 每篇文章的前 3 条评论

REST 方式

// 3 次 API 请求
const user = await fetch('/api/users/1');
const posts = await fetch('/api/users/1/posts?limit=5');
const comments = await Promise.all(
  posts.map(p => fetch(`/api/posts/${p.id}/comments?limit=3`))
);
// 或者后端专门创建一个聚合端点

GraphQL 方式

query {
  user(id: 1) {
    name
    email
    posts(last: 5) {
      title
      comments(last: 3) {
        content
        author { name }
      }
    }
  }
}
// 一次请求获得所有数据

3.3 性能对比

特性 REST GraphQL
缓存 HTTP 缓存天然支持 需要额外缓存方案
网络请求数 可能较多 通常较少
载荷大小 可能包含不需要的数据 客户端精确指定
服务器性能 可控(预定义的数据集) 需防范复杂查询

四、服务端实现

REST 实现(Node.js + Express)

// REST 路由
const express = require('express');
const app = express();

app.get('/api/users/:id', async (req, res) => {
  const user = await db.findUser(req.params.id);
  res.json(user);
});

app.get('/api/users/:id/posts', async (req, res) => {
  const posts = await db.findPostsByUser(req.params.id);
  res.json(posts);
});

GraphQL 实现(Node.js + Apollo Server)

const { ApolloServer, gql } = require('apollo-server');

// 类型定义
const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
    posts: [Post!]!
  }

  type Post {
    id: ID!
    title: String!
    comments: [Comment!]!
  }

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

// 解析器
const resolvers = {
  Query: {
    user: async (_, { id }) => db.findUser(id),
  },
  User: {
    posts: async (user) => db.findPostsByUser(user.id),
  },
};

const server = new ApolloServer({ typeDefs, resolvers });
server.listen(4000);

五、选型建议

选 REST 的场景

  • 简单 CRUD 应用:数据模型简单,不需要嵌套查询
  • 缓存是关键需求:REST 的 HTTP 缓存机制成熟
  • 微服务架构:服务间 REST 接口更加直观
  • 文件上传/下载:处理二进制数据更自然
  • 团队对 REST 更熟悉:降低学习成本

选 GraphQL 的场景

  • 复杂的前端数据需求:不同页面需要不同数据集
  • 多个前端客户端:Web + Mobile 需要不同数据
  • API 需要快速迭代:前端需求变更时后端不需要改接口
  • 数据有复杂的嵌套关系:一次查询获取关联数据

六、混合方案

很多团队采用 REST + GraphQL 混合方案:

方案一:GraphQL 作为 API Gateway
  GraphQL Gateway → REST 服务 A / REST 服务 B / REST 服务 C
  前端只与 GraphQL 交互,后端服务之间用 REST

方案二:一部分用 REST,一部分用 GraphQL
  公开 API → REST(缓存友好)
  内部前端 → GraphQL(灵活取数)

七、总结

REST 和 GraphQL 不是非此即彼的选择。REST 胜在简洁、缓存友好和生态成熟GraphQL 胜在灵活、高效和类型安全。对于新项目,可以考虑从 GraphQL 开始(特别是前后端分离的 SPA 应用);对于已有 REST API,可以逐步引入 GraphQL,没有迁移压力。技术选型的核心是匹配业务需求,而不是追逐热门技术。