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

Sai*_*Akh 18 amazon-s3 aws-appsync

遵循AWS AppSync文档中的此文档/教程.

它指出:

使用AWS AppSync,您可以将它们建模为GraphQL类型.如果您的任何突变都与斗,重点,区域变量,mime类型和localUri领域,SDK将文件上传到亚马逊S3为您服务.

但是,我无法将我的文件上传到我的s3存储桶.我知道该教程缺少很多细节.更具体地说,本教程并未说明NewPostMutation.js需要更改.

我通过以下方式更改了它:

import gql from 'graphql-tag';

export default gql`
mutation AddPostMutation($author: String!, $title: String!, $url: String!, $content: String!, $file: S3ObjectInput ) {
    addPost(
        author: $author
        title: $title
        url: $url
        content: $content
        file: $file
    ){
        __typename
        id
        author
        title
        url
        content
        version
    }
}
`
Run Code Online (Sandbox Code Playgroud)

然而,即使我实施了这些更改,文件也没有上传...

hat*_*ero 21

在"正常工作"(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!
}
Run Code Online (Sandbox Code Playgroud)

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)
}
Run Code Online (Sandbox Code Playgroud)

这假设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))
Run Code Online (Sandbox Code Playgroud)

这个解析器只是告诉AppSync我们想要将存储在DynamoDB中的JSON字符串file作为模型的字段并将其解析为S3Object- 这样,当您对模型进行查询时,而不是返回存储在模型中的字符串.file现场,你会得到包含的对象bucket,regionkey属性,你可以使用它们来构建URL访问S3对象(无论是直接通过S3或使用CDN -这真的取决于您的配置).

确保你有为复杂对象设置的凭据,但是(告诉你我会回到这里).我将使用React示例来说明这一点 - 在定义AppSync参数(端点,身份验证等)时,complexObjectCredentials需要定义一个额外的属性来告诉客户端用于处理S3上载的AWS凭据,例如:

const client = new AWSAppSyncClient({
    url: AppSync.graphqlEndpoint,
    region: AppSync.region,
    auth: {
        type: AUTH_TYPE.AWS_IAM,
        credentials: () => Auth.currentCredentials()
    },
    complexObjectsCredentials: () => Auth.currentCredentials(),
});
Run Code Online (Sandbox Code Playgroud)

假设所有这些都已到位,那么通过AppSync进行S3上传和下载应该可行.