引言
GraphQL 是现代化 Web 开发中的一种全新 API 语言,通过定义数据模型,提供灵活的查询接口,实现前端和后端的平滑协调。在实际使用过程中,RxJS 作为一款优秀的响应式编程框架,可以帮助我们更简单、便捷地处理 GraphQL 服务中的异步数据流,本文将详细介绍 RxJS 在 GraphQL 服务中的应用实例,希望能够对前端开发者有所帮助。
RxJS 和 GraphQL 简介
RxJS
RxJS 是一个响应式编程框架,它通过更简洁的代码描述异步操作的数据流动。在 RxJS 中,一切都是由 Observable、Observer 和 Operator 组成的,Observable 订阅某个数据源,Observer 能够监听数据流中的数据并在收到时作出响应,Operator 则是处理 Observable 数据流的方法集合。
GraphQL
GraphQL 是一种用于 API 的查询语言,同时也是一个满足你数据查询的运行时库。GraphQL 通过定义数据模型来提供灵活的查询接口,让前端开发者能够自由组合数据。GraphQL 服务单一的入口、提供的 GraphQL API 完全由客户端定义,让前端和后端能够顺畅协同工作。
RxJS 在 GraphQL 中的应用场景
实现 GraphQL 后台服务需要使用异步操作进行数据交互,因此 RxJS 很好地解决了 GraphQL 服务异步数据的协调问题。RxJS 通过观察者和可观察值、特定的操作符处理异步数据流,优雅地将 GraphQL 和响应式编程结合起来。
实例 1:基本的 GraphQL 查询
我们首先来看一个简单的 GraphQL 服务查询实例,我们需要获取一个 RESTful 服务提供的用户列表。需要我们调用接口:
------------------------------------------
我们先按照 RxJS 中的方法来实现,如下图所示:
我们通过一个对象 ProjectObservable,以 Observable 的方式获取 RESTful 服务提供的用户列表,并通过 Observer 监听 ProjectObservable 中数据流发出的事件。
我们注意到, 在代码中我们使用了 GraphQL 的 fluent API(链式调用),通过这种 API 可以自由组合和嵌套操作符(如 map、mergeMap 和 filter)来定义复杂的异步数据流:
------ - ---- - ---- ------- ------ - -------- - ---- ----------------- ------ - --- - ---- ---------------------- ------ - ------------- ------------- - ---- ---------------------- ------ - ----------- ------ - ---- ---------------------- ----- ------ - --- -------------- ----- ---------------- ---------- ------ --- ---------------- --- ----- ---------------------- - ------------- ------------------- -- ----------------- -- - ---------------- -------------- ------------------- -- ----- -------------- ------ ---- ------------------ -------- - ------------ ------------ - ---- - - -- ---------- - ---------- -- -- - - --
我们先为方法流提供 searchTerm$ 作为输入流,并在流中连接客户端使用的 HttpLink 和应用级别的认证信息(authLink)进行鉴权。
实例 2:GraphQL 变异和 RxJS 操作的复杂交互
让我们现在看一个更复杂的例子,我们将使用由 React 构建的前端应用程序,并尝试使用 RxJS 响应式编程框架对其进行搜索。
首先,我们将在主组件中提供一个 search 组件(由 input 和 search 按钮组成)、一些样式来显示结果、并为结果设置 Observables 和 Observers:
------ ------ - --------- - ---- -------- ------ - ---------- - ---- ------- ------ --------------------------------- ------ ------------------------ ------ --------------------------- ------ ----------------------------- ------ ---------------------------------- ------ ------------------ ---- ----------------------- ----- ---------------- - --------- -- ---- ------------------------------------ ----- ---------- - -- -- - ---- ------------------ ----------- ---------- - -- --- ----------- ----- ----------- ------------------------- --------------------------------------------- ---------------- ------------ ----- ------------- -------------- ------- --------------- -------------- ------- --------------- ------------------- --------------------- ---------------------- ---------------------- --------------------- --------------------- ---------------------- --------------------- --------------------- ---------------------- ---------------------- --------------- -------- ---------------- ------------ ------ ------------- ------------ ----- ------------- --------------------- --------------------- -------- ------ ---------------------- -- -- ------ -- ------ ------- ----- ------------ ------- --------- - ----- - - -------- --- ----------- --- -------- ------ -- ------------- - ------------ -- --------------- ---------- --- --------- - ----- ------------ -- - ----- ------ - --------------------- ----- ---- - ----- -------------- ------ ---- ------------------ -------- - ------------ ------------ - ---- - - -- ---------- - ---------- -- --- ------ ----- -- ------- - --- --------------------- -- - ----- ----- - ---------------------------------------------------- -------------------------------- ------- -- - ---------------------------------- --- -------- ------------------ ---------------- -- ------------------- ------------------- -- -------------- --------------------- -- - --------------- -------- ---- --- ------ ---------------------------------------- -- -- -------------- - - ----- ------ -- --------------- -------- ---------------------- -------- ------ --- ------ ------- -- --------------------- -- -------- - ----- - ----------- -------- ------- - - ----------- ------ - ----- ---------- ------------ ---- -------- --------- ---------- --- ------ ----------- ------------------ ------------------ ----------------- -- --------------------------------------- -------- ------------- ------- -- -- -------------- ------ -------- -- ---------------------- ----------------- -- - ---- ------------------ ------ -- - --- ------------ -- --------------- ------------- ----------- ----------- ----- ---- ----- --- ----- -- ------ -- - -
这个例子中查询方法流 search$ 启动时,我们将在 input 组件上监听 change 事件,调用 observer.next(event.target.value) 发送搜索词条。接下来,我们使用 RxJS 操作符链解析这个词条:
------- - --- --------------------- -- - ----- ----- - ---------------------------------------------------- -------------------------------- ------- -- - ---------------------------------- --- -------- ------------------ ---------------- -- ------------------- ------------------- -- -------------- --------------------- -- - --------------- -------- ---- --- ------ ---------------------------------------- -- --
- 我们使用 debounceTime 来限制每个搜索操作的时间间隔,避免服务器负载过高。
- 通过使用 filter 方法,我们防止发送空白搜索请求,并解析从 input 组件中发送来的字符串。
- 异步查询使用 mergeMap 方法,我们先将应用程序状态设置为启动的状态,在 Observable 序列中调用 fetchData 方法,然后在请求完成后将 json 数据类型解析并将它们嵌入到 Apollo Client 数据缓存中。
我们还需要提供一个用于为组件下的 search 方法流提供 Observer 的方法。 这是 render 方法所做的事情。它使我们能够把新的客户端请求数据更新到 UI 内,我们向 Observer 提供一个包含 next 和 error 方法的 JavaScript 对象:
-------------- - - ----- ------ -- --------------- -------- ---------------------- -------- ------ --- ------ ------- -- --------------------- --
我们可以通过向应用程序根组件的 search 方法流 subscriber$ 添加此 Observer,来确保我们的 React 前端应用程序能够实时更新。 在以后的实例中我们也会用到。
结论
在本文中,我们探讨了 RxJS 在 GraphQL 服务中的应用实例。我们了解了 GraphQL 和 RxJS 的基本原理,并根据实际例子演示了 RxJS 和 GraphQL 的优雅结合,解决了异步数据流协调问题。我们相信这个实例将对于前端开发者在开发 GraphQL 服务时有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/671f3efb2e7021665efc9474