AppSync S3Object retrieval

2019-06-06 17:44发布

问题:

My files are currently being uploaded to an s3 bucket according to the tutorials provided.

I have a Post type with a file field pointing to an S3Object. S3Object has the values of bucket, key, and region.

I want to allow my users to download their uploaded files, but I cannot access Post > file through a query. This means I cannot get the download URL.

Right now, DynamoDB stores the following for file upon upload (I've changed the values here): {"s3":{"key":"id.pdf","bucket":"my-bucket","region":"my-region"}}

My resolver for Post > file looks like this: { "version": "2017-02-28", "operation": "GetItem", "key": { "id": $util.dynamodb.toDynamoDBJson($ctx.source.id), } }

Response template: $util.dynamodb.fromS3ObjectJson($ctx.result.file)

When I run the query, I get the following error: Error: GraphQL error: Unable to convert {bucket=my-bucket, region=my-region, key=id.pdf} to class java.lang.Object.

回答1:

I believe you need to wrap $util.dynamodb.fromS3ObjectJson($ctx.result.file) in a call to $util.toJson(). Can you kindly change the response mapping template to $util.toJson($util.dynamodb.fromS3ObjectJson($ctx.result.file)) and see if that works?

As a side-note, I think you can achieve the desired effect without making a second call to DynamoDB from the Post.file resolver. Create a "None" datasource and change the Post.file resolver to use it. You can provide a barebones request mapping template such as

{ "version": "2017-02-28", "payload": {} }

and can then change your response mapping template to use the source instead of the result.

$util.toJson($util.dynamodb.fromS3ObjectJson($ctx.source.file))

Since the post will already have been fetched by the time the Post.file field is being resolved the information will already be available in the source. If you needed to fetch the S3Link from a different table than the Post objects then you would need a second DynamoDB call.

Hope this helps and let me know if the call to $util.toJson fixes the issue.

Thanks



回答2:

This solution does not work with a Local datasource of type none any longer, or it's not possible to do this in the aws console at least.

I got the:

MappingTemplate error: Value for field '$[operation]' not found

every time I tried this solution. When I changed datasource to the one that has the file field and used the request resolver:

{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.source.id),
    }
}

and the response resolver:

$util.toJson($util.dynamodb.fromS3ObjectJson($context.source.file))

It worked as it should.