【问题标题】:How to let GraphQL know filenames are images - custom API not creating fixed/fluid images如何让 GraphQL 知道文件名是图像 - 自定义 API 不创建固定/流体图像
【发布时间】:2020-04-17 22:49:16
【问题描述】:

我有一个使用 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 就是其中之一。见附件截图

【问题讨论】:

  • 所以我现在已经开始工作了媒体文件的正确名称,我在 CLI 中使用“gatsby repl”然后是“schema”。这使您能够为您的媒体字段找到正确的名称。然后替换下面示例中的“CMS_Asset”:gatsbyjs.org/docs/schema-customization/… 也包括在 gatsby-node.js 中: const { createRemoteFileNode } = require("gatsby-source-filesystem")
  • 您想在此处添加您的完整解决方案作为答案吗?
  • 是的,我会这样做的——我还在改变事情的最后一个答案——从那以后得到了更多的反馈

标签: gatsby gatsby-image


【解决方案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:输入 gatsby 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
        },
      },
    },
  })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 1970-01-01
    相关资源
    最近更新 更多