使用urql在Svelte中实现GraphQL客户端

使用urql在Svelte中实现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已经成为获取和管理数据的重要方式。urql是一个轻量级且功能强大的GraphQL客户端,特别适合在Svelte应用中使用。本文将详细介绍如何在Svelte项目中集成和使用urql。

安装与基础配置

安装依赖

首先需要安装urql的Svelte绑定包和graphql核心包:

npm install @urql/svelte graphql

创建客户端实例

urql的核心是Client类,它管理所有GraphQL请求和结果:

import { Client, cacheExchange, fetchExchange } from '@urql/svelte';

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

配置认证头信息

在实际应用中,通常需要添加认证信息:

const client = new Client({
  url: 'http://localhost:3000/graphql',
  exchanges: [cacheExchange, fetchExchange],
  fetchOptions: () => {
    const token = getToken();
    return {
      headers: { authorization: token ? `Bearer ${token}` : '' },
    };
  },
});

提供客户端上下文

在Svelte中,我们需要通过上下文API共享客户端实例:

<script>
  import { Client, setContextClient, cacheExchange, fetchExchange } from '@urql/svelte';

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

  setContextClient(client);
</script>

查询数据

基本查询示例

urql提供了queryStore函数来创建响应式查询:

<script>
  import { queryStore, gql, getContextClient } from '@urql/svelte';

  const todos = queryStore({
    client: getContextClient(),
    query: gql`
      query {
        todos {
          id
          title
        }
      }
    `,
  });
</script>

{#if $todos.fetching}
  <p>Loading...</p>
{:else if $todos.error}
  <p>Error: {$todos.error.message}</p>
{:else}
  <ul>
    {#each $todos.data.todos as todo}
      <li>{todo.title}</li>
    {/each}
  </ul>
{/if}

使用查询变量

查询可以接受变量参数:

<script>
  import { queryStore, gql, getContextClient } from '@urql/svelte';

  let limit = 10;
  let from = 0;
  
  $: todos = queryStore({
    client: getContextClient(),
    query: gql`
      query ($from: Int!, $limit: Int!) {
        todos(from: $from, limit: $limit) {
          id
          title
        }
      }
    `,
    variables: { from, limit }
  });

  function nextPage() {
    from += limit;
  }
</script>

<button on:click={nextPage}>Next Page</button>

控制查询执行

可以暂停和恢复查询:

<script>
  import { queryStore, gql, getContextClient } from '@urql/svelte';

  $: todos = queryStore({
    client: getContextClient(),
    query: gql`
      query {
        todos {
          id
          title
        }
      }
    `,
    pause: true
  });

  function startQuery() {
    todos.resume();
  }
</script>

<button on:click={startQuery}>Start Query</button>

刷新查询数据

手动刷新查询数据:

<script>
  import { queryStore, gql, getContextClient } from '@urql/svelte';

  const client = getContextClient();
  $: todos = queryStore({
    client,
    query: gql`
      query {
        todos {
          id
          title
        }
      }
    `
  });

  function refresh() {
    todos.reexecute({ requestPolicy: 'network-only' });
  }
</script>

<button on:click={refresh}>Refresh</button>

数据变更

基本变更示例

使用mutationStore执行变更操作:

<script>
  import { mutationStore, gql, getContextClient } from '@urql/svelte';

  let result;
  const client = getContextClient();
  
  const updateTodo = ({ id, title }) => {
    result = mutationStore({
      client,
      query: gql`
        mutation ($id: ID!, $title: String!) {
          updateTodo(id: $id, title: $title) {
            id
            title
          }
        }
      `,
      variables: { id, title }
    });
  };
</script>

{#if $result?.fetching}
  <p>Updating...</p>
{:else if $result?.error}
  <p>Error: {$result.error.message}</p>
{/if}

错误处理

正确处理变更操作中的错误:

updateTodo({ id, title: newTitle }).then(result => {
  if (result.error) {
    console.error('Operation failed:', result.error);
  } else {
    console.log('Update successful:', result.data);
  }
});

高级特性

请求策略

urql提供了多种请求策略:

  • cache-first (默认) - 优先使用缓存
  • cache-and-network - 返回缓存结果并获取最新数据
  • network-only - 跳过缓存直接请求
  • cache-only - 仅使用缓存
$: todos = queryStore({
  client: getContextClient(),
  query: gql`...`,
  requestPolicy: 'cache-and-network'
});

上下文选项

可以针对特定查询覆盖全局设置:

$: todos = queryStore({
  client: getContextClient(),
  query: gql`...`,
  context: {
    url: 'http://localhost:3000/graphql?debug=true',
    requestPolicy: 'network-only'
  }
});

总结

urql为Svelte应用提供了简洁而强大的GraphQL集成方案。通过queryStoremutationStore,我们可以轻松实现数据的查询和变更,同时利用Svelte的响应式特性实现高效的UI更新。urql的缓存策略和错误处理机制也为构建健壮的应用程序提供了保障。

在实际项目中,可以根据需求进一步探索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、付费专栏及课程。

余额充值