使用纯JS发送GraphQL请求的方法(例如,Lambda@Edge等)

有时候,我想通过Lambda@Edge向特定的端点执行GraphQL的查询。由于Lambda@Edge无法附加层,因此需要使用内置于Lambda的运行时方法来发送HTTP请求。
(实际上,如果将代码和库打包成1MB以下的ZIP文件,可以通过部署该文件来使用第三方的Node库。但在实施时,由于调查不足,我认为这是不可能的。有关详细信息,请参考下方的链接。)

 

由于某种原因,我们在这次使用Node.js的v16系作为运行时。
作为Node的http客户端库,通常会使用axios或node-fetch等。但是,这些库没有被内置在Node16中。
如果可以使用Node.js的v18系,建议使用fetch,它是默认可用的。

在Node.js的v16系列中,只有https可以直接使用,但是由于GraphQL查询的执行方式在使用此功能时很难理解,所以我想写一篇文章来记录并解释这个方法。

突然分享代码

由于错误处理等方面有些是随意的,请在参考时随时添加适当的处理方式。

"use strict";

const https = require("https");

const options = {
  hostname: "hogepiyotest.com", // リクエスト先のホスト名を指定
  path: "/",
  port: 443,
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
};

// 実行したいQuery
const infoQuery = `
query Info($id: ID!) {
  info(id: $id) {
    id
    description
  }
}
`;

const getInfo = (operation, id) => {
  const requestBody = JSON.stringify({
    operationName: operation,
    variables: {
      id: id,
    },
    query: infoQuery,
  });

  return new Promise((resolve, reject) => {
    const req = https.request(options, (res) => {
      let body = "";
      res.on("data", (d) => {
        body += d;
      });
      res.on("end", () => {
        console.log(JSON.parse(body).data);
        resolve(JSON.parse(body).data);
      });
    });

    req.on("error", (error) => {
      console.error(error);
      reject(new Error(error));
    });

    req.write(requestBody);
    req.end();
  });
};

exports.handler = async (event) => {
  const request = event.Records[0].cf.request;
  const path = request.uri;
  // 今回はアクセスされたURLのパスの一番目に、欲しい情報に対応するIDを指定すると仮定
  const pathList = path.split("/");
  const id = pathList[1];

  const fetchedData = await getInfo("info", id);
  // 以下、受け取った内容をご所望の形に整形してください
  ...
};

大致解释

这次的关键点在于如何使用https来发送GraphQL请求。我参考了这个链接进行了实现,并且稍微解释一下。

getInfo函数在GraphQL请求中扮演着一个角色,并在其中使用Promise进行异步处理。
Promise中的https请求是这个异步处理的主要部分。

在这里简要说明一下GraphQL请求。
GraphQL请求可以发送三种数据:查询(query)、操作名称(operationName)和变量(variables)。
查询是必需的,用来描述GraphQL查询。由于GraphQL是通过单一的端点进行操作的,所以响应的数据都依赖于查询。

variables是一个包含传递给查询的变量值的JSON对象,它是一个选项。例如,如果查询需要一个名为id的变量(在查询中显示为$id),您需要按以下方式发送变量。

{
"id":1
}

为了使这个id的值可变,我们在getInfo函数中使其能够接收id。

operationName也可以省略(这里我们明示了)。这是用于指定在包含多个命名操作的查询中执行哪个操作的方法。

在`getInfo`中,将这三个参数作为`requestBody`定义,并发送请求到端点。

只需使用await调用getInfo,即可提取出Promise的内容。
关于接收内容的处理部分,本次没有特别的记述,只需按照喜好进行处理即可。

以下是参考的一种选择:

 

广告
将在 10 秒后关闭
bannerAds