此处的正确方法是使用 AWS AppSync 通过复杂类型执行实际 S3 上传 - 您在此处说明的内容看起来更像是您试图将 base64 编码图像作为字符串保存到我只能假设为的字段中DynamoDB 表条目。但是,要使其正常工作,您需要修改您的突变,以使该file
字段不是 a String!
,而是 a S3ObjectInput
。
在这个“正常工作”(TM)之前,您需要确保在引擎盖下有一些活动部件。首先,您需要确保在 GraphQL 模式中定义的 S3 对象具有适当的输入和类型
enum Visibility {
public
private
}
input S3ObjectInput {
bucket: String!
region: String!
localUri: String
visibility: Visibility
key: String
mimeType: String
}
type S3Object {
bucket: String!
region: String!
key: String!
}
当然,该S3ObjectInput
类型用于上传新文件时使用 - 通过创建或更新嵌入了所述 S3 对象元数据的模型。它可以通过以下方式在突变的请求解析器中处理:
{
"version": "2017-02-28",
"operation": "PutItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($ctx.args.input.id),
},
#set( $attribs = $util.dynamodb.toMapValues($ctx.args.input) )
#set( $file = $ctx.args.input.file )
#set( $attribs.file = $util.dynamodb.toS3Object($file.key, $file.bucket, $file.region, $file.version) )
"attributeValues": $util.toJson($attribs)
}
这是假设 S3 文件对象是附加到 DynamoDB 数据源的模型的子字段。请注意,调用$utils.dynamodb.toS3Object()
设置了复杂的 S3 对象file
,它是模型的一个字段,类型为S3ObjectInput
。以这种方式设置请求解析器会处理将文件上传到 S3(当所有凭据都设置正确时 - 我们稍后会谈到),但它没有解决如何S3Object
返回。这就是需要附加到本地数据源的字段级解析器的地方。本质上,您需要在 AppSync 中创建一个本地数据源,并file
使用以下请求和响应解析器将其连接到模式中的模型字段:
## Request Resolver ##
{
"version": "2017-02-28",
"payload": {}
}
## Response Resolver ##
$util.toJson($util.dynamodb.fromS3ObjectJson($context.source.file))
这个解析器只是告诉 AppSync 我们想要获取存储在 DynamoDB 中的 JSON 字符串file
作为模型的字段并将其解析为S3Object
- 这样,当您查询模型时,而不是返回存储在file
字段,您将获得一个包含 、 和 属性的对象bucket
,region
您key
可以使用这些属性构建 URL 以访问 S3 对象(直接通过 S3 或使用 CDN - 这实际上取决于您的配置)。
但是,请确保您为复杂对象设置了凭据(告诉您我会回到这个问题上)。我将使用一个 React 示例来说明这一点 - 在定义 AppSync 参数(端点、身份验证等)时,complexObjectCredentials
需要定义一个名为的附加属性来告诉客户端使用什么 AWS 凭证来处理 S3 上传,例如:
const client = new AWSAppSyncClient({
url: AppSync.graphqlEndpoint,
region: AppSync.region,
auth: {
type: AUTH_TYPE.AWS_IAM,
credentials: () => Auth.currentCredentials()
},
complexObjectsCredentials: () => Auth.currentCredentials(),
});
假设所有这些都到位,通过 AppSync 的 S3 上传和下载应该可以工作。