此处的正确方法是使用 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 我们想要获取存储在 DynamoDBfile
中作为模型字段的 JSON 字符串并将其解析为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(),
});
假设所有这些都准备就绪,S3 通过 AppSync 上传和下载应该可以工作。