什么是RESTful 或 GraphQL?

RESTful 与 GraphQL 深度解析

在前端的开发过程中,相信 everyone 对 Get、POST 等请求方式都很熟悉,那么这些请求是归于哪种架构或者设计风格可能又不是很熟。现在在这简单的介绍一下以及拿出 GraphQL 架构进行对比。

1. 什么是 RESTful?

REST(Representational State Transfer,表述性状态转移)是一种 架构风格,而不是具体的协议或技术。RESTful API 依据 REST 架构风格设计,使用 HTTP 方法 进行资源操作。

1.1 RESTful 的核心概念

  1. 资源(Resource):一切数据都是资源,每个资源由 URL 唯一标识,系统中的每个对象(如用户、订单)都是一个资源。
  2. URI(Uniform Resource Identifier) :唯一标识资源的路径,如 /getUsersInfo?id=1 表示获取 ID 为 1 的用户。
  3. HTTP 方法 :常见方法如下:
    • GET:获取资源
    • POST:创建资源
    • PUT/PATCH:更新资源
    • DELETE:删除资源
  4. 无状态性:服务器不存储客户端的请求状态,每个请求都应包含所有必要的信息。
  5. 响应格式:通常使用 JSON 作为数据交换格式。
  6. 统一接口(Uniform Interface)
    • 使用 HTTP 方法 表达操作
    • 资源表现形式(JSON、XML、HTML)
    • HATEOAS(超媒体作为应用状态引擎,减少 API 依赖)

1.2 RESTful 的底层原理

RESTful API 依赖于 HTTP 协议,底层涉及:

  • HTTP/1.1HTTP/2 进行通信。
  • 状态码 反映操作结果(如 200 成功,404 资源不存在,500 服务器错误)。
  • CORS(跨域资源共享) 解决跨域问题。
  • OAuth2、JWT 等方式实现身份认证。

1.3 RESTful 示例

1.3.1 获取用户信息(GET 请求)

http 复制代码
GET /getUsersInfo?id=1

响应示例:

json 复制代码
{
  "id": 1,
  "name": "Alice"
}

1.3.2 创建新用户(POST 请求)

http 复制代码
POST /users
Content-Type: application/json

{
  "name": "Charlie"
}

响应示例:

json 复制代码
{
  "id": 3,
  "name": "Charlie"
}

1.4 RESTful 的优缺点

优点:

  • 符合 HTTP 规范,简单直观,开发和测试方便。
  • 缓存友好,可利用 HTTP 缓存机制提升性能。
  • 良好的分离性,前后端分离清晰。
  • 适用于 面向资源 的应用,如 CRUD 操作。
  • 服务器端 无状态 ,易于扩展。

缺点:

  • 请求数据可能冗余 ,例如 /users 可能返回所有用户数据,即使前端只需要 name
  • 难以应对复杂查询 ,需要定义多个端点,如 /users?name=Alice&age=25
  • 版本管理复杂 ,需要维护 /v1/users/v2/users 等。
  • 可能导致 Over-fetching(数据过多)Under-fetching(数据不足)
  • 多次请求 才能获取复杂数据(如获取用户及其订单,需要两次请求)。

2. 什么是 GraphQL?

GraphQL 是由 Facebook 在 2015 年开源的 查询语言(Query Language),提供了一种灵活的 API 查询语言,它允许客户端精准请求所需数据,而不是受限于固定的 RESTful 端点。

2.1 GraphQL 的核心概念

  1. Schema(模式) :使用 Schema 定义 API 的数据结构,例如 User 类型。
  2. Query(查询) :客户端可按需进行灵活数据查询,获取数据的请求,如 query { user(id: 1) { name } }
  3. Mutation(变更) :修改数据的请求,如 mutation { createUser(name: "Charlie") { id name } }
  4. Resolver(解析器):后端逻辑,决定如何获取或修改数据。
  5. Single Endpoint(单一端点) :所有查询都通过 POST /graphql 进行,不同于 RESTful 的多个端点。
  6. Subscription(实时更新):支持 WebSocket 进行实时数据推送。

2.2 GraphQL 的底层原理

GraphQL 的执行涉及:

  • AST(抽象语法树)解析:请求被解析为 AST,进行解析和验证。
  • Resolver 解析器:根据 Schema 执行查询逻辑。
  • 数据聚合(Data Fetching):从数据库、REST API 或其他数据源获取数据。

2.3 GraphQL 示例

2.3.1 查询用户列表

graphql 复制代码
query {
  users {
    id
    name
  }
}

响应示例:

json 复制代码
{
  "data": {
    "users": [
      { "id": 1, "name": "Alice" },
      { "id": 2, "name": "Bob" }
    ]
  }
}

2.3.2 获取单个用户

graphql 复制代码
query {
  user(id: 1) {
    name
  }
}

响应示例:

json 复制代码
{
  "data": {
    "user": { "name": "Alice" }
  }
}

2.3.3 创建用户(Mutation)

graphql 复制代码
mutation {
  createUser(name: "Charlie") {
    id
    name
  }
}

响应示例:

json 复制代码
{
  "data": {
    "createUser": { "id": 3, "name": "Charlie" }
  }
}

2.4 GraphQL 的优缺点

优点:

  • 精确获取所需数据,避免 RESTful API 的冗余数据。
  • 单一端点(/graphql),无需多个 API 路径。
  • 可组合查询,前端可以自由决定请求结构。

缺点:

  • 学习成本较高,需要掌握 Schema、Query、Mutation。
  • 缓存机制复杂,无法直接利用 HTTP 缓存。
  • 性能问题,复杂查询可能导致数据库压力过大。

3. RESTful vs GraphQL 对比

特性 RESTful API GraphQL API
资源端点 多个端点(如 /users, /posts 单一端点(/graphql
数据获取方式 由服务器决定返回数据 由客户端决定返回字段
数据冗余 可能返回过多字段 只返回请求的字段
请求效率 多个请求才能获取完整数据 单次请求可获取所有需要数据
复杂查询 依赖多个端点和查询参数 直接在 Query 语句中定义
HTTP 缓存 可利用浏览器和 CDN 缓存 需定制缓存策略
易用性 易于理解 需要学习 Schema 及查询语法
性能 适合简单 API 复杂查询可能影响数据库性能

4. 何时选择 RESTful vs GraphQL?

  • 选择 RESTful API

    • API 结构稳定,数据不会频繁变化。
    • 需要利用 HTTP 缓存优化性能。
    • 适合公开 API,如 GitHub REST API。
  • 选择 GraphQL

    • 需要前端自由选择数据字段。
    • 需要整合多个数据来源(如合并数据库和第三方 API)。
    • 适用于社交媒体、数据驱动应用,如 Facebook、Twitter。

5. 总结

​ 选 RESTful:就像去餐厅点套餐,简单直接,厨师给你配好了(数据格式固定),适合大部分普通需求。​ 优点:开发快、好维护,新手也能看懂。​ 缺点:想要多点少点菜(调整数据)得让厨师改菜单(改接口)。

​ 选 GraphQL:像吃自助麻辣烫,自己拿夹子随便挑菜(前端按需取数据)。​ 优点:灵活省事(避免多次请求),后端不用频繁改接口。​ 缺点:调料台太复杂(学习成本高),吃太多容易撑(性能优化难)。

简单来说:小项目、简单需求用 REST(省心);复杂系统、前端天天改需求用 GraphQL(省折腾)。

相关推荐
裁二尺秋风25 分钟前
Nginx — Nginx处理Web请求机制解析
前端·nginx
excel29 分钟前
webpack 核心编译器 第五节
前端
曲辒净1 小时前
vue搭建一个树形菜单项目
前端·javascript·vue.js
喝拿铁写前端7 小时前
前端与 AI 结合的 10 个可能路径图谱
前端·人工智能
codingandsleeping7 小时前
浏览器的缓存机制
前端·后端
灵感__idea9 小时前
JavaScript高级程序设计(第5版):扎实的基本功是唯一捷径
前端·javascript·程序员
摇滚侠9 小时前
Vue3 其它API toRow和markRow
前端·javascript
難釋懷9 小时前
JavaScript基础-history 对象
开发语言·前端·javascript
beibeibeiooo9 小时前
【CSS3】04-标准流 + 浮动 + flex布局
前端·html·css3