深入理解urql中的GraphQL订阅功能

深入理解urql中的GraphQL订阅功能

urql The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow. urql 项目地址: https://gitcode.com/gh_mirrors/ur/urql

什么是GraphQL订阅

GraphQL订阅是一种实时通信机制,允许客户端从服务器接收持续更新的数据。与传统的查询和变更不同,订阅建立了一个长期连接,当服务器端数据发生变化时,会自动推送更新到客户端。

urql中的订阅实现

urql通过subscriptionExchange来实现订阅功能,这是一个可配置的交换器(exchange),需要与其他核心交换器一起使用。

基本配置

要启用订阅功能,首先需要在urql客户端中添加订阅交换器:

import { Client, cacheExchange, fetchExchange, subscriptionExchange } from 'urql';

const client = new Client({
  url: 'http://localhost:3000/graphql',
  exchanges: [
    cacheExchange,
    fetchExchange,
    subscriptionExchange({
      forwardSubscription,
    }),
  ],
});

传输协议选择

urql本身不限定具体的传输协议,而是通过forwardSubscription函数来适配不同的订阅实现方式。

1. 使用graphql-ws(推荐)

对于支持新协议graphql-ws的后端,推荐使用这种方式:

import { createClient as createWSClient } from 'graphql-ws';

const wsClient = createWSClient({
  url: 'ws://localhost/graphql',
});

const forwardSubscription = (request) => {
  const input = { ...request, query: request.query || '' };
  return {
    subscribe(sink) {
      const unsubscribe = wsClient.subscribe(input, sink);
      return { unsubscribe };
    },
  };
};
2. 使用subscriptions-transport-ws(旧版)

对于仍在使用Apollo旧版订阅实现的系统:

import { SubscriptionClient } from 'subscriptions-transport-ws';

const subscriptionClient = new SubscriptionClient('ws://localhost/graphql', { 
  reconnect: true 
});

const forwardSubscription = (request) => 
  subscriptionClient.request(request);
3. 使用HTTP Fetch(特殊场景)

某些GraphQL实现(如GraphQL Yoga)支持通过HTTP实现订阅:

const client = new Client({
  url: '/graphql',
  fetchSubscriptions: true,  // 启用fetch订阅
  exchanges: [cacheExchange, fetchExchange],
});

在各框架中的使用

React/Preact中的使用

React中使用useSubscription钩子:

const handleSubscription = (messages = [], response) => {
  return [response.newMessages, ...messages];
};

const Messages = () => {
  const [res] = useSubscription({ query: NEW_MESSAGES_SUBSCRIPTION }, handleSubscription);

  return (
    <ul>
      {res.data?.map(message => (
        <li key={message.id}>{message.from}: "{message.text}"</li>
      ))}
    </ul>
  );
};

Svelte中的使用

Svelte中使用subscriptionStore

<script>
  import { subscriptionStore } from '@urql/svelte';
  
  const messages = subscriptionStore({
    query: NEW_MESSAGES_SUBSCRIPTION
  });
</script>

{#each $messages.data?.newMessages || [] as message}
  <p>{message.from}: "{message.text}"</p>
{/each}

Vue中的使用

Vue中使用useSubscription组合式API:

<script setup>
import { useSubscription } from '@urql/vue';

const handleSubscription = (messages = [], response) => {
  return [response.newMessages, ...messages];
};

const result = useSubscription({
  query: NEW_MESSAGES_SUBSCRIPTION
}, handleSubscription);
</script>

<template>
  <ul>
    <li v-for="msg in result.data" :key="msg.id">
      {{ msg.from }}: "{{ msg.text }}"
    </li>
  </ul>
</template>

核心API直接使用

不依赖框架时,可以直接使用客户端的subscription方法:

const { unsubscribe } = client.subscription(NEW_MESSAGES_SUBSCRIPTION)
  .subscribe(result => {
    console.log('New message:', result.data.newMessages);
  });

// 需要时取消订阅
unsubscribe();

最佳实践

  1. 选择合适的传输协议:优先考虑graphql-ws,它是专为GraphQL订阅设计的新协议

  2. 数据累积处理:利用reducer函数处理连续的数据流,特别适合聊天、实时通知等场景

  3. 资源清理:组件卸载时确保取消订阅,避免内存泄漏

  4. 错误处理:始终处理订阅可能产生的错误

  5. 性能考虑:对于高频更新场景,考虑节流或防抖处理

总结

urql提供了灵活而强大的订阅功能实现,支持多种传输协议和框架集成。通过合理的配置和使用模式,可以轻松实现各种实时数据需求。理解其工作原理和最佳实践,将帮助开发者构建更高效的实时应用。

urql The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow. urql 项目地址: https://gitcode.com/gh_mirrors/ur/urql

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乔嫣忱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值