Я довольно новичок в GraphQL и AWS AppSync и столкнулся с проблемой загрузки файлов (PDF и PNG) из общедоступной корзины S3 через AWS AppSync.Я просмотрел десятки учебных пособий и просмотрел множество документации, и я просто не уверен, что происходит на данный момент.Это может быть не что иное, как недоразумение о природе функций GraphQL или AppSync, но я в полном замешательстве.
Для справки, я в значительной степени получен из других сообщений, таких как Как загрузить файл вAWS S3 с использованием AWS AppSync (в частности, из предложений автора принятого ответа), но ни одно из решений (или вариантов, которые я пытался) не работает.
Факты
- Корзина S3 общедоступна, т. Е. Включенные папки и файлы не привязаны к отдельным пользователям с учетными данными Cognito
- Файлы загружаются на S3 вне AppSync (поэтому нетМутация GraphQL);это загрузка файла вручную
- Схема работает для всех других запросов и мутаций
- Мы используем AWS Cognito для аутентификации пользователей и запросов
Сокращенная схема иЭлементы DynamoDB
Вот сокращенная версия соответствующих типов схем GraphQL:
type MetroCard implements TripCard {
id: ID!
cardType: String!
resIds: String!
data: MetroData!
file: S3Object
}
type MetroData implements DataType {
sourceURL: String!
sourceFileURL: String
metroName: String!
}
type S3Object {
bucket: String!
region: String!
key: String!
}
Метаданные о файлах хранятся в DynamoDB и выглядят примерно так:
{
"data": {
"metroName": "São Paulo Metro",
"sourceFileURL": "http://www.metro.sp.gov.br/pdf/mapa-da-rede-metro.pdf",
"sourceURL": "http://www.metro.sp.gov.br/en/your-trip/index.aspx"
},
"file": {
"bucket": "test-images",
"key": "some_folder/sub_folder/bra-sbgr-metro-map.pdf",
"region": "us-east-1"
},
"id": "info/en/bra/sbgr/metro"
}
Устранители запросов / ответов VTL
Для нашего запроса getMetroCard(id: ID!): MetroCard
шаблоны отображения довольно ванильные.Шаблон запроса является стандартным запросом к таблице DynamoDB.Шаблон ответа является базовым $util.toJson($ctx.result)
.
. Для распознавателя на уровне поля в MetroCard.file
мы подключили локальный источник данных с пустой полезной нагрузкой {}
для запроса и следующие дляответ (см. ссылочную ссылку для обоснования):
$util.toJson($util.dynamodb.fromS3ObjectJson($context.source.file)) // we've played with this bit in a couple of ways, including simply returning $context.result but no change
Результаты
Все поля запроса разрешаются соответствующим образом;однако поле file
неизбежно всегда возвращает null
независимо от того, на что сопоставлен преобразователь уровня поля.Интересно, что я заметил, что в журналах CloudWatch значение context.result
действительно изменяется с null
до {}
с указанным выше шаблоном сопоставления.
Вопросы
Учитывая вышеизложенное, у меня есть несколько вопросов:
- Требуется ли загрузка файла AppSync для загрузки файлов на S3 с учетными данными пользователя посредством мутации с обработчиком сложного объекта, чтобы сделать их доступными для извлечения?
- Как должен выглядеть успешный ответ в возврате консоли AppSync, т. Е. У меня нет клиентской реализации (например, приложения React Native) для проверки успешной загрузки файлов?Если говорить прямо, это действительно получение файлов, а я просто не знаю?(Примечание: на самом деле я кратко протестировал его с клиентом React Native, но ничего не отображалось, поэтому с тех пор я просто использую консоль AppSync в качестве направления.)
- Имеет ли смысл удалять файлПроцесс загрузки полностью из нашей схемы?(Я предполагаю, что ответы, которые мне нужны, показывают, что AppSync просто не был создан для такой передачи файлов, и поэтому нам нужно переосмыслить наш подход.)
Обновление
Я начал играть с источником данных для MetroCard.file
согласно предложению этой недавней публикации https://stackoverflow.com/a/52142178/5989171. Если я сделаю источник данных таким же, как база данных, хранящаяметаданные файла, теперь я получаю ошибку, упомянутую в ссылке, но его решение, похоже, не работает для меня.В частности, теперь я получаю следующее:
"message": "Value for field '$[operation]' not found."
Наше решение
Для нашего случая использования мы решили пойти дальше и использовать AWSМодуль «Усиление хранилища», как предлагается здесь: https://twitter.com/presbaw/status/1040800650790002689. Несмотря на это, я держу этот вопрос открытым и без ответа, потому что мне просто искренне любопытно, что я здесь не понимаю, и у меня такое чувство, что яне единственный!