连接 AWS Appsync Graphql Link 作为 Gatsbyjs 数据源

Posted

技术标签:

【中文标题】连接 AWS Appsync Graphql Link 作为 Gatsbyjs 数据源【英文标题】:Connecting AWS Appsync Graphql Link as a Gatsbyjs Datasource 【发布时间】:2019-11-03 17:07:40 【问题描述】:

正在努力设置一个 GatsbyJS 插件,该插件使用 IAM 身份验证从 AWS AppSync 获取。我不断收到一个错误,我无法找出问题所在。

我在 graphql 链接方面没有大量经验,也找不到关于如何在这种情况下做好它的好文档。

这是我的插件 gatsby-node.js 文件的样子:

const uuidv4 = require(`uuid/v4`)
const invariant = require(`invariant`)
const fetch = require(`node-fetch`)
const  createHttpLink  = require(`apollo-link-http`)
const  buildSchema, printSchema  = require(`graphql`)
const  makeRemoteExecutableSchema, transformSchema, introspectSchema, RenameTypes  = require(`graphql-tools`)
const AUTH_TYPE = require('aws-appsync/lib/link/auth-link').AUTH_TYPE
const AWS = require('aws-sdk');
const  createAppSyncLink  = require('aws-appsync');

exports.sourceNodes = async (  actions, createNodeId, cache, createContentDigest , options ) => 
  const  createNode  = actions
  delete options.plugins
  const  typeName, fieldName, refetchInterval, HOST, PATH, REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY  = options
  const url = HOST + PATH

  // making sure things are required properly
  invariant(
    typeName && typeName.length > 0,
    `gatsby-source-graphql requires option \`typeName\` to be specified`
  )
  invariant(
    fieldName && fieldName.length > 0,
    `gatsby-source-graphql requires option \`fieldName\` to be specified`
  )

  // Link to appsync
  const fetcherLink = createHttpLink(
    uri: url,
    fetch: fetch
  )

  const type = AUTH_TYPE.AWS_IAM

  AWS.config.update(
    region: REGION,
    credentials: new AWS.Credentials(
      accessKeyId: AWS_ACCESS_KEY_ID,
      secretAccessKey: AWS_SECRET_ACCESS_KEY
    )
  );

  const credentials = AWS.config.credentials;

  const link = createAppSyncLink(
    url: url,
    region: REGION,
    auth:  type, credentials ,
    resultsFetcherLink: fetcherLink,
  );

  // Schema Creation
  let introspectionSchema
  const cacheKey = `gatsby-source-graphql-schema-$typeName-$fieldName`

  let sdl = await cache.get(cacheKey)

  console.log('sdl', sdl)
  if (!sdl) 
    introspectionSchema = await introspectSchema(link)
    sdl = printSchema(introspectionSchema)
   else 
    introspectionSchema = buildSchema(sdl)
  

  await cache.set(cacheKey, sdl)

  const remoteSchema = makeRemoteExecutableSchema(
    schema: introspectionSchema,
    link,
  )

  // Node creation
  const nodeId = createNodeId(`gatsby-source-graphql-$typeName`)
  const node = createSchemaNode(
    id: nodeId,
    typeName,
    fieldName,
    createContentDigest,
  )
  createNode(node)

  const resolver = (parent, args, context) => 
    context.nodeModel.createPageDependency(
      path: context.path,
      nodeId: nodeId,
    )
    return 
  

  const schema = transformSchema(remoteSchema, [
    new StripNonQueryTransform(),
    new RenameTypes(name => `$typeName_$name`),
    new NamespaceUnderFieldTransform( typeName, fieldName, resolver ),
  ])

  addThirdPartySchema( schema )

  if (process.env.NODE_ENV !== `production`) 
    if (refetchInterval) 
      const msRefetchInterval = refetchInterval * 1000
      const refetcher = () => 
        createNode(
          createSchemaNode(
            id: nodeId,
            typeName,
            fieldName,
            createContentDigest,
          )
        )
        setTimeout(refetcher, msRefetchInterval)
      
      setTimeout(refetcher, msRefetchInterval)
    
  


function createSchemaNode( id, typeName, fieldName, createContentDigest ) 
  const nodeContent = uuidv4()
  const nodeContentDigest = createContentDigest(nodeContent)
  return 
    id,
    typeName: typeName,
    fieldName: fieldName,
    parent: null,
    children: [],
    internal: 
      type: `GraphQLSource`,
      contentDigest: nodeContentDigest,
      ignoreType: true,
    ,
  

这是我的错误信息:

TypeError:无法读取未定义的属性“存储”

client.js:147 [gatsby-source-appsync]/[aws-appsync]/lib/client.js:147:27

client.js:139 ApolloLink.request [gatsby-source-appsync]/[aws-appsync]/lib/client.js:139:23

bundle.umd.js:188 ApolloLink.request [gatsby-source-appsync]/[aws-appsync]/[apollo-link]/lib/bundle.umd.js:188:35

bundle.umd.js:188 ApolloLink.request [gatsby-source-appsync]/[aws-appsync]/[apollo-link]/lib/bundle.umd.js:188:35

bundle.umd.js:188 ApolloLink.request [gatsby-source-appsync]/[aws-appsync]/[apollo-link]/lib/bundle.umd.js:188:35

link.js:84 Object.execute [gatsby-source-appsync]/[apollo-link]/lib/link.js:84:18

linkToFetcher.js:7 [gatsby-source-appsync]/[graphql-tools]/dist/stitching/linkToFetcher.js:7:56

introspectSchema.js:50 [gatsby-source-appsync]/[graphql-tools]/dist/stitching/introspectSchema.js:50:42

introspectSchema.js:31 步骤 [gatsby-source-appsync]/[graphql-tools]/dist/stitching/introspectSchema.js:31:23

introspectSchema.js:12 Object.next [gatsby-source-appsync]/[graphql-tools]/dist/stitching/introspectSchema.js:12:53

introspectSchema.js:6 [gatsby-source-appsync]/[graphql-tools]/dist/stitching/introspectSchema.js:6:71

新的承诺

introspectSchema.js:2 __awaiter [gatsby-source-appsync]/[graphql-tools]/dist/stitching/introspectSchema.js:2:12

introspectSchema.js:41 introspectSchema [gatsby-source-appsync]/[graphql-tools]/dist/stitching/introspectSchema.js:41:12

gatsby-node.js:60 Object.exports.sourceNodes /workspace/plugins/gatsby-source-appsync/gatsby-node.js:60:33

之前没有太多使用 graphql 链接。有什么帮助吗?

【问题讨论】:

【参考方案1】:

对于您的场景,最好只使用来自aws-appsynccreateAuthLink,因为createAppSyncLink 为您似乎不需要的离线场景引入了很多东西(另外,完整链接appsync 依赖于 apollo 的查询管理器在操作上下文中插入缓存)。

这样的事情可能对你有用:

const  ApolloLink  = require(`apollo-link`)
const  createAuthLink  = require("aws-appsync");

const link = ApolloLink.from([
    createAuthLink(
        url: url,
        region: REGION,
        auth:  type, credentials ,
    ),
    fetcherLink
]);

【讨论】:

以上是关于连接 AWS Appsync Graphql Link 作为 Gatsbyjs 数据源的主要内容,如果未能解决你的问题,请参考以下文章

AWS AppSync - 从 AppSync 控制台运行时的 GraphQL 查询超时

AWS GraphQL Appsync - 无法担任角色

如何使用 AWS appsync (GraphQL) 禁用自省查询?

如何在部署前从@aws-cdk/aws-appsync 检索 schema.graphql 文件

我们可以在不使用 GraphQL 的情况下在项目中实施 AWS-Appsync 吗?

aws amplify appsync 中的 Graphql 突变错误