[英]How to upload an image to AWS S3 using GraphQL?
我正在上傳一個base64字符串,但GraphQL被掛起了。 如果我將字符串切片少於50,000個字符就可以了。 在50,000個字符之后,graphQL永遠不會使其成為解析函數,但不會產生錯誤。 在較小的字符串上,它工作得很好。
const file = e.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
const imageArray = reader.result;
this.context.fetch('/graphql', {
body: JSON.stringify({
query: `mutation s3Upload($img: String!) {
s3Upload(file: $img) {
logo,
}
}`,
variables: {
img: imageArray,
},
}),
}).then(response => response.json())
.then(({ data }) => {
console.log(data);
});
}
const s3Upload = {
type: S3Type,
args: {
file: { type: new NonNull(StringType) },
},
resolve: (root, args, { user }) => upload(root, args, user),
};
const S3Type = new ObjectType({
name: 'S3',
fields: {
logo: { type: StringType },
},
});
這里正確的方法是使用AWS AppSync通過復雜類型執行實際的S3上傳 - 您在此處說明的內容更像是您嘗試將base64編碼的圖像作為字符串保存到字段中,我只能假設為DynamoDB表條目。 但是,要使其工作,您需要修改變異,使file
字段不是String!
,但是一個S3ObjectInput
。
在“正常工作”(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()
的調用會設置復雜的S3對象file
,該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中的JSON字符串作為模型的file
字段並將其解析為S3Object
- 這樣,當您對模型進行查詢時,而不是返回存儲的字符串在file
字段中,您將獲得一個包含bucket
, region
和key
屬性的對象,您可以使用這些對象構建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(),
});
假設所有這些都已到位,那么通過AppSync進行S3上傳和下載應該可行。
AWS AppSync( https://aws.amazon.com/appsync/ )為此提供了稱為“復雜對象”的功能,您可以在其中獲得S3對象和輸入的類型:
type S3Object {
bucket: String!
key: String!
region: String!
}
input S3ObjectInput {
bucket: String!
key: String!
region: String!
localUri: String
mimeType: String
}
然后你可以做這樣的事情來定義這個對象作為另一種類型的一部分:
type UserProfile {
id: ID!
name: String
file: S3Object
}
然后指定一個突變來添加它:
type Mutation {
addUser(id: ID! name: String file: S3ObjectInput): UserProfile!
}
您的客戶端操作需要指定適當的存儲桶,密鑰(帶有文件擴展名),區域等。
更多信息: https : //docs.aws.amazon.com/appsync/latest/devguide/building-a-client-app-react.html#complex-objects
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.