GraphQL 是一种用于 API 的查询语言和运行时环境,由 Facebook 开发并开源,旨在解决传统 RESTful API 存在的过度获取或获取不足数据(Over-fetching/Under-fetching)等问题。其核心理念是让客户端精确指定需要的数据,从而提高 API 交互的灵活性和效率。

一、GraphQL 的核心特点

  1. 按需获取数据
    客户端可以在一个请求中精确指定所需的字段,避免 REST API 中“获取多余数据”或“多次请求才能获取足够数据”的问题。
    例如,查询用户信息时,客户端可只请求 idnameavatar,而无需返回不需要的 addressphone 等字段。

  2. 单一端点
    GraphQL 通常通过一个单一端点(如 /graphql)处理所有请求,而非 REST 中多个资源端点(如 /users/orders)。所有查询和修改操作都通过这个端点完成。

  3. 强类型 schema
    服务器端定义一个严格的类型系统(Schema),描述所有可查询的资源、字段及其关系。客户端的所有查询都必须符合该 schema,服务器会在执行前验证查询的合法性,减少错误。

  4. 支持复杂关系查询
    轻松处理资源间的嵌套关系,例如在一次请求中同时获取“用户信息”及其关联的“订单列表”和“订单包含的商品”,无需多次请求。

二、基本概念与操作

  1. Schema(类型定义)
    服务器端用 GraphQL Schema Definition Language (SDL) 定义数据结构,例如:

    # 定义用户类型
    type User {
     id: ID!       # 非空ID
     name: String! # 非空字符串
     age: Int      # 可选整数
     orders: [Order!]! # 关联的订单列表(非空数组)
    }
    
    # 定义订单类型
    type Order {
     id: ID!
     product: String!
     price: Float!
     date: String
    }
    
    # 定义查询入口
    type Query {
     getUser(id: ID!): User  # 根据ID查询用户
     getOrders: [Order!]!    # 查询所有订单
    }
    
    # 定义修改数据的入口(类似REST的POST/PUT)
    type Mutation {
     createUser(name: String!, age: Int): User # 创建用户
    }
  2. Query(查询数据)
    客户端发送查询请求,指定所需字段:

    # 查询ID为1的用户,仅获取name和其订单的product
    query {
     getUser(id: "1") {
       name
       orders {
         product
       }
     }
    }

    服务器返回的 JSON 结构与查询结构完全一致:

    {
     "data": {
       "getUser": {
         "name": "Alice",
         "orders": [
           {"product": "手机"},
           {"product": "电脑"}
         ]
       }
     }
    }
  3. Mutation(修改数据)
    用于创建、更新或删除数据(类似 REST 的 POST/PUT/DELETE):

    # 创建新用户
    mutation {
     createUser(name: "Bob", age: 25) {
       id  # 创建后返回新用户的ID
       name
     }
    }

三、与 RESTful API 的对比

特性 RESTful API GraphQL
数据获取 固定结构,可能过度/不足获取 客户端按需指定,精确获取
端点数量 多个(每个资源一个端点) 单一端点
版本控制 通常通过 URL(如 /v1/users 无需版本,通过 schema 兼容扩展
关系查询 需多次请求(如先查用户再查订单) 一次请求完成嵌套关系查询
学习成本 低(基于 HTTP 标准) 较高(需学习 SDL、查询语法等)

四、适用场景

  • 客户端需要灵活获取不同结构数据(如多端应用:Web、移动端需求不同)。
  • 资源间关系复杂,需要频繁查询嵌套数据。
  • 希望减少网络请求次数,优化性能。

但 GraphQL 并非银弹,对于简单场景(如数据结构固定的 API),REST 可能更简单直接。

总结

GraphQL 以“客户端主导数据获取”为核心,通过强类型 schema 和灵活的查询语法,解决了传统 API 的数据冗余和请求效率问题,特别适合复杂数据关系和多端应用场景。目前已被 GitHub、Twitter、Airbnb 等众多企业采用,成为 API 设计的重要选择之一。