使用纯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的内容。
关于接收内容的处理部分,本次没有特别的记述,只需按照喜好进行处理即可。
以下是参考的一种选择: