Итак, после некоторых замечательных советов по поводу чата 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 случае. В моем случае это было не из-за странного способа, которым я все настроил!
Более простой способ найти его для меня - использовать CLI: type 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
},
},
},
})
}