RESTful 与 GraphQL 深度解析
在前端的开发过程中,相信 everyone 对 Get、POST 等请求方式都很熟悉,那么这些请求是归于哪种架构或者设计风格可能又不是很熟。现在在这简单的介绍一下以及拿出 GraphQL 架构进行对比。
1. 什么是 RESTful?
REST(Representational State Transfer,表述性状态转移)是一种 架构风格,而不是具体的协议或技术。RESTful API 依据 REST 架构风格设计,使用 HTTP 方法 进行资源操作。
1.1 RESTful 的核心概念
- 资源(Resource):一切数据都是资源,每个资源由 URL 唯一标识,系统中的每个对象(如用户、订单)都是一个资源。
- URI(Uniform Resource Identifier) :唯一标识资源的路径,如
/getUsersInfo?id=1
表示获取 ID 为 1 的用户。 - HTTP 方法 :常见方法如下:
GET
:获取资源POST
:创建资源PUT/PATCH
:更新资源DELETE
:删除资源
- 无状态性:服务器不存储客户端的请求状态,每个请求都应包含所有必要的信息。
- 响应格式:通常使用 JSON 作为数据交换格式。
- 统一接口(Uniform Interface) :
- 使用 HTTP 方法 表达操作
- 资源表现形式(JSON、XML、HTML)
- HATEOAS(超媒体作为应用状态引擎,减少 API 依赖)
1.2 RESTful 的底层原理
RESTful API 依赖于 HTTP 协议,底层涉及:
- HTTP/1.1 或 HTTP/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 的核心概念
- Schema(模式) :使用 Schema 定义 API 的数据结构,例如
User
类型。 - Query(查询) :客户端可按需进行灵活数据查询,获取数据的请求,如
query { user(id: 1) { name } }
。 - Mutation(变更) :修改数据的请求,如
mutation { createUser(name: "Charlie") { id name } }
。 - Resolver(解析器):后端逻辑,决定如何获取或修改数据。
- Single Endpoint(单一端点) :所有查询都通过
POST /graphql
进行,不同于 RESTful 的多个端点。 - 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(省折腾)。