AWS AppSyncドキュメントの this docs/tutorial に従います。
状態:
AWS AppSyncを使用すると、これらをGraphQLタイプとしてモデル化できます。いずれかのミューテーションにバケット、キー、リージョン、mimeType、およびlocalUriフィールドを持つ変数がある場合、SDKはファイルをAmazon 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
}
}
`
それでも、これらの変更を実装した後でも、ファイルはアップロードされませんでした...
この「ジャスト・ワークス」(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()
を呼び出すと、_S3ObjectInput
_型のモデルのフィールドである複雑なS3オブジェクトfile
が設定されます。この方法でリクエストリゾルバーを設定すると、S3へのファイルのアップロードが処理されます(すべての資格情報が正しく設定されたら-すぐに触れます)が、_S3Object
_戻る。これは、ローカルデータソースに接続されたフィールドレベルリゾルバが必要になる場所です。本質的に、AppSyncでローカルデータソースを作成し、次のリクエストおよびレスポンスリゾルバを使用してスキーマのモデルのfile
フィールドに接続する必要があります。
_## Request Resolver ##
{
"version": "2017-02-28",
"payload": {}
}
## Response Resolver ##
$util.toJson($util.dynamodb.fromS3ObjectJson($context.source.file))
_
このリゾルバーは、モデルのfile
フィールドに対してDynamoDBに保存されているJSON文字列を取得し、それを_S3Object
_に解析することをAppSyncに伝えるだけです。モデルは、file
フィールドに格納されている文字列を返す代わりに、bucket
、region
、およびkey
プロパティを含むオブジェクトを取得できます。 S3オブジェクトにアクセスするためのURLを作成するために使用します(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(),
});
_
これらすべてが整っていると仮定すると、AppSyncを介したS3のアップロードとダウンロードが機能するはずです。
ディスカッションに追加するだけです。モバイルクライアントの場合、amplify(またはAWSコンソールから行う場合)は、変異呼び出しをオブジェクトにカプセル化します。カプセル化が存在する場合、クライアントは自動アップロードしません。そのため、awsコンソールでミューテーションコールを直接変更して、アップロードfile: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とAndroidの両方が、@ hatboyzeroが概説したことを行うとコンテンツを喜んでアップロードします。
[編集]少し調べたところ、おそらく2.7.3で修正されたと思われます https://github.com/awslabs/aws-mobile-appsync-sdk-Android/issues/11 。彼らはおそらくiOSに対処しましたが、私はチェックしませんでした。