无法使用 Amazon Amplify 从 Lambda 调用 GraphQL
Posted
技术标签:
【中文标题】无法使用 Amazon Amplify 从 Lambda 调用 GraphQL【英文标题】:Failing to call GraphQL from Lambda using Amazon Amplify 【发布时间】:2021-03-26 16:44:59 【问题描述】:我正在使用 Amazon Amplify 创建一个访问 AppSync GraphQL 终端节点内容的函数。 使用命令行我创建了新函数和 API,我可以从我的前端应用程序中正确调用它,但是,我不断收到此错误:
2020-12-16T01:39:40.524Z 979abb8d-4d64-4929-937a-03b0cb495174 INFO error posting to appsync: Error: Request failed with status code 401
at createError (/var/task/node_modules/axios/lib/core/createError.js:16:15)
at settle (/var/task/node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (/var/task/node_modules/axios/lib/adapters/http.js:244:11)
at IncomingMessage.emit (events.js:326:22)
at endReadableNT (_stream_readable.js:1223:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
config:
url: 'https://y63v24inqneirizeuiig7x5g54.appsync-api.us-east-1.amazonaws.com/graphql',
method: 'post',
data: '"query":"query listCompetitions \\n listCompetitions \\n items \\n createdAt\\n id\\n likes\\n updatedAt\\n votes\\n websiteImageKey\\n websiteUrl\\n user \\n username\\n imageKey\\n \\n websiteDescription\\n \\n \\n\\n"',
headers:
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json;charset=utf-8',
'x-api-key': '7aeiasrvb5bczhmlt2nnbpfuyi',
'User-Agent': 'axios/0.21.0',
'Content-Length': 284
,
我用来从我的函数中调用 GraphQL 的代码是来自 link。
const graphqlData = await axios(
url: process.env.API_MAINDATA_GRAPHQLAPIENDPOINTOUTPUT,
method: "post",
headers:
"x-api-key": process.env.API_MAINDATA_GRAPHQLAPIIDOUTPUT,
,
data:
query: print(listCompetition),
,
);
Amplify 将 URL 和 KEY 添加到 env 中,我已经为相关 API 添加了 API_KEY 身份验证,所以我不明白为什么我仍然得到401 error
。
我注意到的一件事是文档说要使用:
'x-api-key': process.env.API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT
但是_GRAPHQLAPIKEYOUTPUT
没有生成,所以我改用_GRAPHQLAPIIDOUTPUT
,不确定这是否发生了变化,或者我是否缺少环境常量。
【问题讨论】:
A401
错误是由于您没有正确的授权。需要_GRAPHQLAPIKEYOUTPUT
才能访问x-api-key
。
@yudhiesh 是的,奇怪的是我的 lambda .env 上没有密钥,有什么想法可以强制它重新创建吗?
【参考方案1】:
您是否正确签署了您的请求?如果您还没有,请查看AWS.Signers.V4。
我遇到了和你类似的问题,我最终实现了一个专用的 Lambda 函数来执行 GraphQL 操作。这样一来,只要我想执行 GraphQL 操作,我就可以调用我的 Lambda 函数。
类似:
/* Amplify Params - DO NOT EDIT
API_XXXXXX_GRAPHQLAPIENDPOINTOUTPUT
API_XXXXXX_GRAPHQLAPIIDOUTPUT
ENV
REGION
Amplify Params - DO NOT EDIT */
const AWS = require('aws-sdk')
const https = require('https')
const urlParse = require('url').URL
const APPSYNC_URL = process.env['API_XXXXXX_GRAPHQLAPIENDPOINTOUTPUT']
const REGION = process.env['REGION']
const ENDPOINT = new urlParse(APPSYNC_URL).hostname.toString()
//
// execute a graphql operation via appsync
//
exports.handler = async ( item, operation, operationName ) =>
const request = createSignedRequest(
ENDPOINT,
item,
operation,
operationName,
REGION,
APPSYNC_URL,
)
return getResponseFromApi(ENDPOINT, request)
//
// create a signed graphql operation request
//
const createSignedRequest = (
endpoint,
item,
operation,
operationName,
region,
url,
) =>
const request = new AWS.HttpRequest(url, region)
request.method = 'POST'
request.path = '/graphql'
request.headers.host = endpoint
request.headers['Content-Type'] = 'application/json'
request.body = JSON.stringify(
query: operation,
operationName: operationName,
variables: item,
)
const signer = new AWS.Signers.V4(request, 'appsync', true)
signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate())
return request
//
// send a request to the appsync api and return the response data
//
const getResponseFromApi = (endpoint, request) =>
return new Promise((resolve, reject) =>
const httpRequest = https.request(
...request, host: endpoint ,
(result) =>
result.on('data', (data) =>
resolve(JSON.parse(data.toString()))
)
,
)
httpRequest.write(request.body)
httpRequest.end()
)
【讨论】:
以上是关于无法使用 Amazon Amplify 从 Lambda 调用 GraphQL的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有 Amplify 的情况下使用 Amazon Cognito
AWS Amplify 和 amazon-cognito-identity-js 的区别?
使用 Amazon Amplify快速创建简单的 Android 应用程序
基于 Amazon Amplify 构建自己的首个 iOS 应用程序