如何使用AWS的AppSync上传文件AWS S3

问题描述 投票:13回答:2

继AWS的AppSync文档this docs/tutorial

它指出:

有了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
    }
}
`

然而,即使我已经实现了这些变化,该文件没有得到上传...

amazon-s3 aws-appsync
2个回答
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!
}

通过创建或更新在其中所述S3对象元数据被嵌入到一个模型的方式 - S3ObjectInput型,当然,在上传新文件时是使用。它可以通过以下的突变请求解析器来处理:

{
    "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为模型的file领域的JSON字符串,并将其解析为一个S3Object - 这样一来,当你做模型的查询,而不是返回存储字符串在file领域,你会得到包含您可以用它来创建一个URL来访问S3对象的bucketregionkey属性的对象(无论是直接通过S3或使用CDN - 这真的取决于您的配置)。

一定要确保你有设置了复杂的对象凭证,但是,(告诉你,我会回到这个)。我将使用一个作出反应的例子来说明这一点 - 定义你的AppSync参数(端点,AUTH等)时,有一个附加属性称为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上传和下载应该工作。


1
投票

我想补充的讨论。对于移动客户端,放大(或如果从AWS控制台做)将封装突变电话成一个对象。如果封装存在客户端将不会自动上传。所以,你可以直接修改突变呼叫AWS控制台,以便上传文件:S3ObjectInput是在调用的参数。这是怎么回事我测试的最后一次(2018年12月)后的文档。

你会改变这种调用结构:

 type Mutation {
        createRoom(
        id: ID!,
        name: String!,
        file: S3ObjectInput,
        roomTourId: ID
    ): Room
}

相反,自动生成呼叫喜欢:

type Mutation {
    createRoom(input: CreateRoomInput!): Room
}
input CreateRoomInput {
    id: ID
    name: String!
    file: S3ObjectInput
}

一旦你做出这种改变iOS和如果你做什么@hatboyzero概述了Android将愉快地上传您的内容。

[编辑]我做了一些研究,按说这已被固定在2.7.3 https://github.com/awslabs/aws-mobile-appsync-sdk-android/issues/11。他们有可能解决的iOS,但我没有检查。

© www.soinside.com 2019 - 2024. All rights reserved.