在这个 "just works" (TM) 的背后有一些需要注意的关键点。首先,您需要确保在 GraphQL schema 中定义了适当的输入和类型来支持 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对象元数据。 可以通过以下方式在mutation的请求解析器中处理它:
{
"version": "2017-02-28",
"operation": "PutItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($ctx.args.input.id),
},
"attributeValues": $util.toJson($attribs)
}
假设S3文件对象是连接到DynamoDB数据源的模型的子字段。请注意,调用$utils.dynamodb.toS3Object()
设置了复杂的S3对象file
,该对象是具有类型S3ObjectInput
的模型的字段。以这种方式设置请求解析器会处理将文件上传到S3(当所有凭据都正确设置时 - 我们稍后会提及),但它并没有解决如何获取S3Object
的问题。这就是连接到本地数据源的字段级解析器变得必要的地方。实际上,您需要在AppSync中创建一个本地数据源,并使用以下请求和响应解析器将其连接到模型的file
字段的模式中:
{
"version": "2017-02-28",
"payload": {}
}
$util.toJson($util.dynamodb.fromS3ObjectJson($context.source.file))
这个解析器告诉AppSync我们想要获取模型中file
字段中存储的JSON字符串并将其解析为一个S3Object
对象。这样,在查询模型时,它会返回一个包含bucket
、region
和key
属性的对象,你可以使用它们来构建访问S3对象的URL(直接通过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上传和下载应该可以正常工作。