GraphQL是一种查询语言,它可以帮助开发者更好的管理应用程序的数据。GraphQL中的subscription是一种实时的数据获取方式,它能够使客户端实时收到服务端的数据更新通知。本文将介绍GraphQL中的subscription使用方法,并提供一些示例代码。
Subscription是什么?
Subscription是GraphQL中一种实时的数据获取方式。相比查询和变更,Subscription使得客户端可以实时地获得服务端可能的数据改变。
Subscription 的用法类似于GraphQL中的查询语句,不同之处在于订阅会创建一个 WebSocket 连接,并监听它们之间的数据传输。当服务端相应的数据发生变化时,它会通过WebSocket连接将数据实时推送给客户端。
Subscription的使用
使用Subscription需要以下步骤:
1. 在服务端的GraphQL Schema中定义Subscription类型
在服务端定义Subscription类型,Subscription类型应该包含客户端所需要监听数据的字段。比如,客户端需要监听用户行为,那么我们需要在服务端的GraphQL Schema中定义一个subscription类型:
type Subscription { userActivity(userId: ID!): UserActivity! }
其中,userActivity是我们所定义的字段名,它接收一个参数userId,类型为ID,返回值为UserActivity类型。这个Subscription类型代表着客户端可以在服务端请求userActivity数据,并且服务端可能会实时地发送更新给客户端。
2. 编写subscription的解析器
在服务端,我们需要编写一个处理userActivity字段的解析器。这个解析器将接收从客户端发送过来的subscription请求,并处理给定的参数,使用某些方法来获取新的userActivity数据。最后,使用函数pubsub.publish
,将新数据推送给绑定的客户端。
-- -------------------- ---- ------- ----- - ------ - - --------------------------------- ----- ------ - --- --------- ----- --------------------- - ------------------------ ----- --------- - - ------------- - ------------- - ---------- -------- ----- -- - -- ------------------------ ----- ------- - ------------------------------------------ ------ ------------------------------ -- -- -- --------- - ------------- -------- ----- -- - -- ---- -------- ---- ----- ------------------- - ----------------------------- ----- ------- - ------------------------------------------ ----------------------- - ------------- ------------------- --- -- -- --
这个解析器函数首先创建PubSub实例,当有连接的客户端发来请求时,解析器发现此连接还没有订阅该频道,所以只需创建一个订阅传输通道并返回即可,GraphQL-JS库内部的pubsub.asyncIterator(channel)
函数可以实现这个功能。
如果有来自Mutation的用户活动更新,解析器将使用getUserActivity()函数获取新的userActivity数据。最后,使用函数pubsub.publish将新数据推送给订阅过该频道的客户端。
3. 在客户端使用GraphQL客户端库
在客户端,我们需要使用GraphQL客户端库进行请求subscription。如果您使用的是Relay Modern或Apollo Client,这已经得到了良好的支持。
但如果您需要实现自定义的GraphQL客户端,可以使用Subscription.js这个库,在客户端使用它来执行Subscription查询和建立WebSocket连接。下面是一个使用原生fetch和Websockets API 的示例:
-- -------------------- ---- ------- ----- -- - --- ----------------------------------------- --------------------------- -- -- - -- --------- ----- ----- - - ------------ --------------------- ---- - -------------------- -------- - -- ---- ------ - - -- ----- ---- - - ------- --- -- ----- --------- - - ------- ------- -------- - --------------- ------------------- -- ----- ---------------- ------ ---------- ---- --- -- ----------------------------------- --- ------------------------------ ------- -- - -- ------ ------- ---------------------- ---------------- ---
这段JS代码会发起一个WebSocket的连接并发送一个subscription的请求。代码中的query变量,是我们通过WebSocket发起的请求所发送的subscription的查询语句。变量vars则是用来提供给GraphQL语句的参数。
收到的WebSocket消息应该和从HTTP POST和GET请求得到的一样。其返回数据被当做WebSocket消息的“data”属性传递。最后收到的WebSocket消息将在控制台中显示。
订阅 示例
现在,我们以一个简单的实例来演示Subscription由于配有WebSocket实时收到数据的过程。我们使用Apollo Server、React和Subscription.js完成本示例.
服务器端实现
首先我们创建一个GraphQL的服务。下面是一个使用了Express框架和Apollo Server的例子。
-- -------------------- ---- ------- --- ----- - ------------- ---- ------ - - --------------------------------- ----- ------ - --- --------- ----- --------------------- - ------------------------ ----- -------- - ---- ---- ------------ - --- --- ----- ------- ------- ------- - ---- ------------ - ---------------- ----- ------------ - ---- ----- - ---------------- ----- ------------ - ---- -------- - ---------------------- ---- ----- -------- ------- --------- ------------ - -- ----- ------------- - --- ----- --------- - - ------ - ------------- ----- - -- -- -- - ----- ------------ - ------------------ ------ ------------ - ------------ - ----- -- -- --------- - ------------------- ----- - --- ----- ------ -- -- - ----------------- - - --- ----- ------ -- ------------------------------------- - ------------- ----------------- --- ------ ------------------ -- -- ------------- - ------------- - ---------- ----- - -- -- -- - ------ -------------------------------------------- -- -- -- -- ----- ------ - --- -------------- --------- ---------- --- ----- --- - ---------- ---
这里的resolvers中,Mutation.updateUserActivity函数用来更新用户活动,使用pubsub.publish(USER_ACTIVITY_CHANGED, { userActivity: usersActivity[id] });函数将更新的数据推送给所有订阅了该频道的客户端。
Subscription.userActivity({ id })
是客户端请求的subscription,调用pubsub.asyncIterator(USER_ACTIVITY_CHANGED)
函数创建websocket描述符,返回是一个可迭代的对象。
客户端实现
在客户端,我们使用Subscription.js来从服务器端订阅数据的更新。使用react hooks(useEffect和useState)将获得websocket的请求并处理websocket消息。此外,还将使用Subscription来监听来自服务器的数据更新。
在App.js中编写以下代码:
-- -------------------- ---- ------- ------ - ---------- -------- - ---- -------- ------ - ------------------ - ---- ----------------------------- ------ --- ---- -------------- ------ - --------------- - ---- ---------------------- ----- ------ - --- ------------------------------------------------- - ---------- ----- --- ----- ------------------------ - ---- ------------ ----------------- ---- - ---------------- ---- - -- ---- ------ - - -- -------- ----- - ----- -------------- ---------------- - --------------- ----- - ----- ------- - - ----------------------------------------- - ---------- - --- -- -- --- ------------ -- - -- ---------- ------- -------------------------------------- -- ----------- ------ - ---- ---------------- -------- ---- ---- -------------- ----- ------- ------- ------------------ ------ ----- ------- --------- -------------------- ------ ----- --------- ----- ---------------------- ------ ------ -- - ------ ------- ----
总结
通过这篇文章,您可以学习到GraphQL中subscription的使用方法。这是一个非常强大的特性,可以让客户端实时地收到服务端数据的更新。Subscription与传统的Ajax轮询相比,具有更好的性能和代码可读性。当您开发一个实时的应用程序时,subscription会毫不犹豫地让您的代码更简洁和高效。
除了以上的示例,GraphQL还有很多其他的功能和应用场景。如果您现在使用的RESTful API存在一些问题,可以考虑使用GraphQL和它的subscription, 或者其他特性来实现您的应用程序。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64685911968c7c53b0893b5e