2

我有一个使用 gatsby-source-apiserver 访问的自定义 api 端点。我的数据库中有没有转换为图像节点的图像 - 即允许 childimagesharp

在我的graphql中,我有这个结构:

query MyQuery {
  allSubmissions {
    edges {
      node {
        works {
          mediaItems {
            sourceFilename
          }
        }
      }
    }
  }
}

sourceFilename 是一个字符串,如“thisisanimage.jpg” - 如果我在其上附加一个 url,如“ http://example.com/media ”,则图像工作正常。我不确定如何继续,我查看了 createResolvers 但不完全了解如何实现它。

这是我迄今为止尝试过的 - 似乎没有做太多(除了在我的终端中获得“发生任何事情”的评论,但不是下一个......

exports.createResolvers = ({
  actions,
  cache,
  createNodeId,
  createResolvers,
  store,
  reporter,
}) => {
  const { createNode } = actions
  reporter.info(anything happening?)
  createResolvers({
    submissions: {
      works: {
        mediaItems: {
          type: File,
          resolve(sourceFilename, args, context, info) {
            reporter.info(
              Resolving source: ${sourceFilename} ${args} ${context} ${info}
            )
            return createRemoteFileNode({
              url:
                "https://example.com/media/" +
                sourceFilename.sourceFilename,
              store,
              cache,
              createNode,
              createNodeId,
              reporter,
            })
          },
        },
      },
    },
  })
}

可能很重要的一点是,works 是一个 mediaItems 数组,它本身就是一个字段数组,其中 sourceFilename 就是其中之一。请参阅随附的屏幕截图

上述查询的graphQL结果

4

1 回答 1

1

因此,在对 Spectrum Gatsby 聊天提出了一些很好的建议之后,我有了一些解决方案: https ://spectrum.chat/gatsby-js/general/getting-relative-images-to-work-with-a-custom-api-using- gatsby-source-apiserver~a0805b02-6e2b-4be6-ab1a-ae6d3cc53fab

一种方法是将代码放在 gatsby-node.js 中。这可能不是最好的方法,但它确实有效。

第一个问题是以 GraphQL 看到的方式查找字段的名称。您可以使用文档资源管理器通过查询来挖掘包含您的图像 URL 的媒体项目的类型名称。这通常在 Pascal Case 中。就我而言,这不是由于我设置东西的奇怪方式!

对我来说找到它的一种更简单的方法是使用 CLI: typegatsby repl并发出schema命令。

在我的情况下,类型名称是submissionsWorksMediaItems

然后我发现我可以使用它来下载图像并为我提供 childImageSharp 功能:

const { createRemoteFileNode } = require("gatsby-source-filesystem")

exports.createResolvers = ({
  actions,
  cache,
  createNodeId,
  createResolvers,
  store,
  reporter,
}) => {
  const { createNode } = actions
  createResolvers({
    submissionsWorksMediaItems: {
      imageFile: {
        type: `File`,
        resolve(source, args, context, info) {
          return createRemoteFileNode({
            url:
              `https://example.com/media/${source.filename}`,
            store,
            cache,
            createNode,
            createNodeId,
            reporter,
            })

        },
      },
    },
  })
}

在我的情况下,我发现我遇到了一些文件不在服务器上的问题——这产生了一个 404 错误,导致构建失败(尽管它在开发模式下工作)。所以我然后改用以下代码(再次从spectrum.chat中读取线程以获取所有上下文:

const { createRemoteFileNode } = require("gatsby-source-filesystem")

const imageNodes = new Map()
const getImageUrl = source =>
  `https://example.com/media/${source.filename}`
exports.sourceNodes = ({
  actions,
  cache,
  createNodeId,
  getNodesByType,
  store,
  reporter,
}) => {
  const { createNode } = actions
  const imageDownloads = []
  const submissions = getNodesByType("submissions")
  submissions.forEach(node => {
    node.works &&
      node.works.forEach(({ mediaItems }) => {
        mediaItems &&
          mediaItems.forEach(mediaSource => {
            const imageUrl = getImageUrl(mediaSource)
            imageDownloads.push(
              createRemoteFileNode({
                url: imageUrl,
                store,
                cache,
                createNode,
                createNodeId,
                reporter,
              })
                .then(result => {
                  if (!result) {
                    return reporter.warn(`Could not download ${imageUrl}`)
                  }
                  imageNodes.set(imageUrl, result)
                })
                .catch(err => {
                  reporter.warn(err)
                })
            )
          })
      })
  })
  return Promise.all(imageDownloads)
}
exports.createResolvers = ({ createResolvers }) => {
  createResolvers({
    submissionsWorksMediaItems: {
      imageFile: {
        type: `File`,
        resolve(source, args, context, info) {
          const imageUrl = getImageUrl(source)
          if (imageNodes.has(imageUrl)) {
            return imageNodes.get(imageUrl)
          }
          return null
        },
      },
    },
  })
}
于 2020-04-17T14:49:16.970 回答