GraphQL 是一种用于 API 开发的查询语言和运行时环境,由 Facebook 在 2012 年首次提出。它采用了一种声明式的方式定义 API 的输出数据结构,使得客户端能够更加精准地获取所需数据,从而降低了数据获取的成本和网络传输量。
设计思想
GraphQL 的设计思想可以总结为以下几个方面:
1. 精确地描述数据需求
GraphQL 采用了以查询为中心的数据获取方式,即客户端会发出一个查询请求,服务端则返回该查询所需的数据。这种方式与传统的 RESTful API 的方式有所不同,RESTful API 的数据获取方式是针对资源的,一般需要根据访问路径的不同获取到不同的资源。
因此,GraphQL 可以精确地描述客户端所需的数据结构和数据格式,避免了客户端端需要进行多次请求和处理的情况,提高了效率和开发速度。
2. 强类型系统
GraphQL 具有强类型系统的特点,即定义了丰富的数据类型和结构,这些类型和结构可以在定义 Schema 时进行定义,并在运行时进行验证。这样做可以在一定程度上减少程序运行时的错误和不可预期情况。
3. 集成性
GraphQL 并不是一个完整的解决方案,它只是一种查询语言和底层实现的接口规范,因此可以和其他语言和框架进行集成和使用。
架构
GraphQL 的架构可以分为三层:Schema 层、服务层和执行层。
Schema 层
在 GraphQL 中,Schema 层是定义类型、方法、参数、返回值及其他元数据的核心部分。它定义了客户端与服务端之间数据的格式、交互方式及校验规则。
GraphQL Schema 有如下几个部分组成:
1. Query
Query 类型是 GraphQL 中的一个必需类型,定义了客户端可以查询的 API 的入口。它通常包含与某项查询相关的字段和参数,以及该查询需要返回的数据结构。
type Query { user(id: ID!): User! books(title: String!): [Book]! }
2. Mutation
Mutation 类型描述了可以修改数据的操作,例如添加、更新或删除数据。Mutation 与 Query 类型类似,但它们主要用于修改数据而非仅仅查询数据。
type Mutation { addUser(input: UserInput!): User! updateUser(id: ID!, input: UserInput!): User! }
3. Subscription
Subscription 类型定义了客户端可以订阅的实时事件,例如 Websocket 连接状态、新消息、用户在线状态等。GraphQL 通过使用 Async Iterator 将这些事件实现了长连接能力,开发者可以定义触发事件的源头。
type Subscription { newMessage(roomId: ID!): Message! }
4. Enum
Enum 类型定义了可选取的值集合,例如媒体类型、产品类型等。
enum MediaType { IMAGE AUDIO VIDEO }
5. Input
Input 类型定义了传递给 Mutation 或 Field 的数据参数。输入对象不同于 Query 和 Mutation,它仅包含字段参数,不包含查询条件。
input UserInput { name: String! age: Int! }
6. Type
Type 类型定义了包括自定义类型、接口和联合类型在内的复杂数据类型。例如,User 和 Book 就是自定义类型。
-- -------------------- ---- ------- ---- ---- - --- --- ----- ------- ------ ------- ------ ------- - ---- ---- - --- --- ------ ------- ------- ------- ----- ---- -
服务层
服务层是 GraphQL 程序的核心工作,它通常包含 Query、Mutation、Subscription 的实现代码,并负责与数据库或其他 API 进行交互。
GraphQL 的服务层可以由任何编写 API 的服务端语言编写,例如 Python、Node.js、Java 等。
执行层
执行层是处理客户端发来的请求并返回响应的组件,它根据客户端的请求,定位并执行相应的 Query 或 Mutation,并通过服务层与后端进行交互。
执行层还需要校验查询请求的语法和结构,并在服务层执行时负责输入和输出的序列化和反序列化。
示例代码
GraphQL 示例代码如下:
-- -------------------- ---- ------- ---- ----- - -------- ----- ----- ------------ --------- ------- - ---- -------- - -------------- ------------ ----- -------------- ---- ------ ------------ ----- - ---- ------------ - ------------------ ----- -------- - ---- --------- - ----- ----- ----- - ----- --------- - ----- ------- ---- ---- - ---- ---- - --- --- ----- ------- ------ ------- ------ ------- - ---- ---- - --- --- ------ ------- ------- ------- ----- ---- -
使用 Node.js 的实现代码示例如下:
-- -------------------- ---- ------- ----- ------- - ------------------- ----- - ----------- - - --------------------------- ----- - ----------- - - ------------------- ----- --- - ---------- -- -- ------ ----- ------ - ------------- ---- ----- - -------- ----- ----- ------------ --------- ------- - ---- -------- - -------------- ------------ ----- -------------- ---- ------ ------------ ----- - ---- ------------ - ------------------ ----- -------- - ---- --------- - ----- ----- ----- - ----- --------- - ----- ------- ---- ---- - ---- ---- - --- --- ----- ------- ------ ------- ------ ------- - ---- ---- - --- --- ------ ------- ------- ------- ----- ---- - --- -- -- ----- -- ----- ---- - - ----- -- -- - -- --------- -- ------ -- -- - -- --------- -- -- -- -------- -- -------- -- ----- -- -- - -- --------- -- ----------- -- --- ----- -- -- - -- --------- -- -- -- ------------ -- ----------- -- ------ -- -- - -- ------- - -- -- ----- ------- ---- ------------------- ------------- ------- ------- ---------- ----- --------- ----- ---- -- ----- ---------------- -- -- ---------------- ------ -- --------------------------
学习和指导意义
GraphQL 与传统的 RESTful API 相比,具有更高的开发效率、更灵活的数据获取方式和更好的 API 安全性等优点。它的设计思想和具体实现方式值得前端工程师学习和研究。
在实际开发中,GraphQL 可以更加精确地满足客户端需求,降低请求次数和网络传输量,提高效率和用户体验。同时也可以帮助开发团队提升 API 的可维护性和可扩展性,降低后续维护和开发成本。
在学习和使用 GraphQL 时,开发者需要掌握其基本原理、使用方法和一些常见问题和解决方案。同时也需要了解其实现细节和最佳实践,才能更加灵活和高效地应用到实际项目中。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/648ee3f648841e9894d49d87