使用 Fetch API 执行 GraphQL 查询和变体

GraphQL 简介

GraphQL 是从远程服务器查询数据的强大工具,也是我构建 API 的首选方式。对一些人来说,学习它可能有一定难度,因为教程通常使用 Apollo 或 Relay 等工具进行编写。

这些工具很不错,但通常更适用于复杂项目。在某些情况下,最好选择更轻量级的方法,并且不要通过添加额外的库增加包大小。

在这种情况下,你可以直接使用浏览器中提供的工具,在本快速教程中,我们将使用在你的浏览器中通常可用的 fetch

让我们首先简单地回顾一下 fetch 是什么以及它如何通常与 REST API 一起使用,在这之后我们就可以开始执行简单的 GraphQL 查询了。

使用 Fetch 进行 GET 请求

Fetch 是用于发送网络请求的现代替代品,取代了较旧的 XMLHttpRequest 工具。它解决了从服务器获取数据时出现的一些问题,例如 Promise 链式处理。

虽然我们不会在本文详细讨论较旧的 XMLHttpRequest,但重要的是因历史原因你需要知道 fetch 在较旧的浏览器中不受支持。

关于 fetch 在浏览器之外的使用,在 Node.js 17 中你可以作为实验性功能直接使用它,在较早版本中,你可以安装比如 node-fetch 库。

以下是一个用于获取数据简单请求示例:

js 复制代码
const url = 'https://query1.finance.yahoo.com/v8/finance/chart/BTC-USD'

const options = {
  method: 'GET',
}

fetch(url, options)
  .then((response) => {
    return response.json()
  })
  .then((data) => {
    const res = data.chart.result
    console.info(res)
    return res
  })
  .catch((err) => {
    console.log('err', err)
  })

我们可以看到在 fetch 函数中传入了两个参数,即 URLoptions 参数。

options 用于附加配置,比如请求的方法、头部信息、跨源资源共享(CORS)配置以及 POST 请求时的主体内容。

随后的 .then() 调用允许我们链式处理异步 promise,这意味着你首先需要等待来自 API 的结果。如果成功,我们将获得响应,并使用 .json() 方法进行转换。

然后再次等待转换结果,在这里最终可以将数据记录到控制台上。

json 复制代码
{
  "data": {
    "allFilms": {
      "films": [
        {
          "title": "A New Hope",
          "releaseDate": "1977-05-25"
        },
        {
          "title": "The Empire Strikes Back",
          "releaseDate": "1980-05-17"
        }
      ]
    }
  }
}

你会注意到 .catch() 方法尚未被触发。如果一切正常运行,只有成功的回调函数会被执行;但是,如果我们在请求过程中遇到错误,则会触发错误回调。

使用 Fetch 进行 GraphQL 查询

在先前的示例中,我们使用了雅虎金融的公共 REST API 来执行 GET 请求以检索数据。在第二个示例中,我们需要 Star Wars API 的 GraphQL 接口。

GraphQL 提供了所谓的模式内省,它允许我们轻松地记录可以从服务器检索到什么数据,你可以在文档链接中看到。

为了执行 GraphQL 查询,我们需要使用 POST 方法,设置内容为 application/json,并且将字符串化的 GraphQL 文档发送至 JSON 主体。

附加到请求的 GraphQL 文档将如下所示:

js 复制代码
query ($first: Int) {
  allFilms(first: $first) {
   films {
    title
    releaseDate
   }
  }
}

查询类似于 REST API 中的 GET 请求,只检索数据。使用 GraphQL,我们需要准确描述要检索的数据。你可以看到我们已经指定了要检索具有标题和发布日期的电影。

$first 是所谓的变量,这是必要的以将动态数据传递给查询,并允许我们从查询中获取前 n 个电影。现在让我们转换成 JavaScript 代码:

js 复制代码
const url = 'https://swapi-graphql.netlify.app/.netlify/functions/index';

const GET_FILMS = `query ($first: Int) {
  allFilms(first: $first) {
   films {
    title
    releaseDate
   }
  }
}`;

const options = {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: GET_FILMS,
    variables: {
      first: 2
    }
  })
};

const fetchAPI = async () => {
  try {
    const result = await fetch(
      url,
      options
    );
    const data = await result.json();
    console.info(data);
  } catch (err) {
    console.info(err)
  }
}
await fetchAPI();

我们已经为 GraphQL API 和我们的 GraphQL 文档定义了 URL。在这种情况下,我们需要将选项指定为第二个参数。

如上所述,选项方法需要设置为 POST,并且内容应该设置为 application/jsonbody 应该是有两个键的字符串化 JSON:

  • query:我们将传递 GraphQL 文档
  • variables:这些变量应该与服务器上文件和模式中的变量定义匹配

你还可以注意到,在第一个使用 GET 请求的示例中, 我们使用了 .thenable() Promise 链接方式,但在此处我们已经使用了 async await

现在,当我们执行结果时,我们会得到以下结果:

json 复制代码
{
  "data": {
    "allFilms": {
      "films": [
        {
          "title": "A New Hope",
          "releaseDate": "1977-05-25"
        },
        {
          "title": "The Empire Strikes Back",
          "releaseDate": "1980-05-17"
        }
      ]
    }
  }
}

总结

这是对 GraphQL 查询获取用法的简要介绍,变体的原理实际上与查询相同,即传递查询和变量。在复杂的项目中,你应该使用 GraphQL 客户端,如 Apollo、Relay 或其他。

当你需要将项目规模保持在最低限度时,获取具有重要作用。Axios 也是一种很好的获取方式。使用获取时,请务必考虑浏览器支持。

相关推荐
Dazer0075 分钟前
Edge 浏览器绕过 HTTPS 证书错误
前端·https·edge
元让_vincent12 分钟前
Spark 2.0:面向 Web 的 3DGS 可视化与大场景渲染平台详解
前端·3d·spark·渲染·轻量化·3dgs·lod
KaMeidebaby29 分钟前
卡梅德生物技术快报|酵母双杂交 cDNA 文库构建与蛋白互作筛选流程
服务器·前端·数据库·人工智能·算法
沐风___35 分钟前
App 上架之后:如何看数据、获取用户与持续迭代产品
服务器·前端·数据库
AAA大运重卡何师傅(专跑国道)1 小时前
力扣hot100
服务器·前端·数据库
GISer_Jing1 小时前
前端沙箱开源项目推荐(React/Next/Vue优先)
前端·react.js·开源
云水一下2 小时前
CSS3从零基础到精通(三):动感地带——过渡、动画、变形与响应式
前端·css3
KaMeidebaby2 小时前
卡梅德生物技术快报|Western Blot 实验应用:肺肠轴机制研究全流程技术解析
前端·数据库·人工智能·算法·百度
MageGojo2 小时前
做节日活动页时,如何用 API 快速生成对联内容
javascript·python·节日·对联生成
达达爱吃肉2 小时前
claude 接入deepseek 运行报错
java·服务器·前端