在 GraphQL 中使用 GraphQL-Subscriptions 实现实时数据更新的方法

在 GraphQL 中使用 GraphQL-Subscriptions 实现实时数据更新

什么是 GraphQL-Subscriptions?

GraphQL-Subscriptions 是一个用于实现 GraphQL 实时数据更新的库,它可以与任何支持 WebSocket 协议的客户端库搭配使用,如 GraphQL-JS、Apollo-Client 等。使用 GraphQL-Subscriptions 可以像使用 PubSub 一样,让客户端实时地订阅服务器端的数据更新。

如何使用 GraphQL-Subscriptions?

首先,我们需要创建一个用于保存订阅者的存储对象:

let subscriptions = {};

然后,我们可以在 GraphQL 的 schema 中定义一个 Subscription 类型,用于订阅数据:

type Subscription {
  postAdded: Post
}

在 resolver 中定义订阅的操作,这里以一个添加文章的例子进行说明:

const subscriptionResolver = {
  postAdded: {
    subscribe: () => pubsub.asyncIterator("POST_ADDED"),
    resolve: (payload) => {
      return payload;
    },
  },
};

在 subscribe 方法中,我们返回 pubsub 对象的一个 asyncIterator,这个方法会在有新文章添加时自动触发。在 resolve 方法中,我们返回最新添加的文章对象。

最后,我们需要将 Subscription 类型加入到 schema 中,并在服务器启动时创建 WebSocket 服务器:

import { SubscriptionServer } from "subscriptions-transport-ws";
import { execute, subscribe } from "graphql";
import { createServer } from "http";

const schema = new GraphQLSchema({
  query: Query,
  mutation: Mutation,
  subscription: Subscription, // 加入 Subscription 类型
});

// 创建服务器
const server = createServer(app);

server.listen(PORT, () => {
  // 创建 WebSocket 服务器
  new SubscriptionServer(
    {
      execute,
      subscribe,
      schema,
    },
    {
      server: server,
      path: "/subscriptions",
    }
  );
});

现在,我们可以在客户端使用 WebSocket 客户端库来订阅数据更新,例如使用 Apollo-Client:

import { ApolloClient } from "apollo-client";
import { WebSocketLink } from "apollo-link-ws";
import { split } from "apollo-link";
import { getMainDefinition } from "apollo-utilities";
import { InMemoryCache } from "apollo-cache-inmemory";

const httpLink = new HttpLink({ uri: "/graphql" }); // 注意,httpLink 和 wsLink 的 uri 不一样
const wsLink = new WebSocketLink({
  uri: `ws://${window.location.host}/subscriptions`,
  options: {
    reconnect: true,
  },
});

const link = split(
  ({ query }) => {
    const { kind, operation } = getMainDefinition(query);
    return kind === "OperationDefinition" && operation === "subscription";
  },
  wsLink,
  httpLink
);

const client = new ApolloClient({
  link,
  cache: new InMemoryCache(),
});

接着,我们可以在组件中使用 Apollo-Client 提供的 useSubscription Hook 来订阅数据:

import { gql } from "apollo-boost";
import { useSubscription } from "@apollo/react-hooks";

const POST_ADDED_SUBSCRIPTION = gql`
  subscription {
    postAdded {
      id
      title
      content
    }
  }
`;

function PostList() {
  const { data, loading, error } = useSubscription(POST_ADDED_SUBSCRIPTION);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
    <ul>
      {data.postAdded.map((post) => (
        <li key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.content}</p>
        </li>
      ))}
    </ul>
  );
}

现在,当服务器端有新文章添加时,客户端将自动订阅到最新数据更新并进行渲染。

总结

GraphQL-Subscriptions 是一个用于实现实时数据更新的库,可以与任何支持 WebSocket 协议的客户端库搭配使用。使用 GraphQL-Subscriptions 可以让客户端实时地订阅服务器端的数据更新,并可以像使用 PubSub 一样实现数据的实时更新。本文通过一个添加文章的例子详细地介绍了在 GraphQL 中使用 GraphQL-Subscriptions 实现实时数据更新的方法,并包含了示例代码。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b46060add4f0e0ffd4cd58