如何使用 AppSync 从 S3 下载公开可用的 pdf 和 png 文件

Posted

技术标签:

【中文标题】如何使用 AppSync 从 S3 下载公开可用的 pdf 和 png 文件【英文标题】:How to download publicly available pdf and png files from S3 with AppSync 【发布时间】:2019-02-19 19:28:48 【问题描述】:

我是 GraphQL 和 AWS AppSync 的新手,我在通过 AWS AppSync 从公共 S3 存储桶下载文件(PDF 和 PNG)时遇到了问题。我查看了数十个教程并翻阅了大量文档,但我不确定此时发生了什么。这可能只是对 GraphQL 或 AppSync 功能的本质的误解,但我完全被难住了。

作为参考,我大量参考了 How to upload file to AWS S3 using AWS AppSync 等其他帖子(具体来说,来自已接受答案作者的建议),但没有一个解决方案(或我尝试过的变体)有效。

事实

S3 存储桶可公开访问 - 即,包含的文件夹和文件不与具有 Cognito 凭据的个人用户绑定 文件在 AppSync 之外上传到 S3(因此没有 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 并不是为这样的文件传输而构建的,因此我们需要重新考虑我们的方法。)

更新

根据最近这篇帖子https://***.com/a/52142178/5989171 的建议,我已经开始使用MetroCard.file 的数据源。如果我使数据源与存储文件元数据的数据库相同,我现在会收到 ref 中提到的错误,但他的解决方案似乎对我不起作用。具体来说,我现在得到以下信息:

"message": "Value for field '$[operation]' not found."

我们的解决方案

对于我们的用例,我们决定继续使用 AWS Amplify Storage 模块,如下所示:https://twitter.com/presbaw/status/1040800650790002689。尽管如此,我仍然保持这个问题的开放和未回答,因为我真的很好奇我在这里不理解什么,而且我感觉我不是唯一一个!

【问题讨论】:

【参考方案1】:
$util.toJson($util.dynamodb.fromS3ObjectJson($context.source.file))

您只能在您的 DynamoDB 将 file 字段保存为格式:"s3":"key":"file.jpg","bucket":"bucket_name/folder","region":"us-east-1"

时使用它

【讨论】:

以上是关于如何使用 AppSync 从 S3 下载公开可用的 pdf 和 png 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AWS AppSync 将文件上传到 AWS S3

在 IOS 上使用 AWS AppSync 将图像上传到 S3

使用send_file从Amazon S3下载文件吗?

Appsync/GraphQL 是实时显示缩减的基于 S3 的时间序列数据的良好解决方案吗?

从 S3 获取非公开数据

在 React 中使用 AWS Amplify Appsync 上传图像