在 中使用管道解析器 AWS AppSync - AWS AppSync

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

在 中使用管道解析器 AWS AppSync

注意

我們現在主要支援 APPSYNC_JS 執行期及其文件。請考慮在此處使用 APPSYNC_JS 執行期及其指南

AWS AppSync 提供透過單位解析器將 GraphQL 欄位連接至單一資料來源的簡單方法。不過,執行單一操作可能還是不夠。管道解析程式的功能是對資料來源依序執行操作。在 中建立函數API,並將其連接至管道解析器。每個函數執行結果都會輸送到下一個函數,直到沒有要執行的函數。使用管道解析器,您現在可以直接在 中建置更複雜的工作流程 AWS AppSync。在此教學課程中,您會建置一個簡單的圖片檢視應用程式,而使用者可以透過此應用程式來張貼圖片和檢視朋友所張貼的圖片。

一鍵設定

如果您想要在 中自動設定 GraphQL 端點, AWS AppSync 並設定所有解析器和必要的 AWS 資源,您可以使用下列 AWS CloudFormation 範本:

Blue button labeled "Launch Stack" with an arrow icon indicating an action to start.

這個堆疊會在您的帳戶中建立下列資源:

  • IAM AWS AppSync 存取您帳戶中資源的角色

  • 2 個 DynamoDB 資料表

  • 1 個 Amazon Cognito 使用者工具

  • 2 個 Amazon Cognito 使用者集區群組

  • 3 個 Amazon Cognito 使用者集區使用者

  • 1 AWS AppSync API

在 AWS CloudFormation 堆疊建立程序結束時,您會收到建立的三個 Amazon Cognito 使用者各一封電子郵件。每封電子郵件都包含臨時密碼,用於以 Amazon Cognito 使用者身分登入 AWS AppSync 主控台。儲存這些密碼,以供教學課程其餘內容使用。

手動設定

如果您想要手動透過 AWS AppSync主控台完成程序 step-by-step,請遵循下列設定程序。

設定您的非 AWS AppSync 資源

會與兩個 DynamoDB 資料表API通訊:存放圖片的相片資料表,以及存放使用者之間關係的朋友資料表。API 設定為使用 Amazon Cognito 使用者集區作為身分驗證類型。下列 AWS CloudFormation 堆疊會在 帳戶中設定這些資源。

Blue button labeled "Launch Stack" with an arrow icon indicating an action to start.

在 AWS CloudFormation 堆疊建立程序結束時,您會收到建立的三個 Amazon Cognito 使用者各一封電子郵件。每封電子郵件都包含臨時密碼,您可用來以 AWS AppSyncAmazon Cognito 使用者身分登入主控台。儲存這些密碼,以供教學課程其餘內容使用。

建立您的 GraphQL API

若要在 API中建立 GraphQL AWS AppSync:

  1. 開啟 AWS AppSync 主控台,然後選擇從速寫開始,然後選擇開始

  2. 將 的名稱API設定為 AppSyncTutorial-PicturesViewer

  3. 選擇 Create (建立)。

AWS AppSync 主控台會使用API金鑰身分驗證模式API為您建立新的 GraphQL。您可以使用 主控台來設定 GraphQL 的其餘部分,API並在本教學課程的其餘部分對其執行查詢。

設定 GraphQL API

您需要使用剛建立的 Amazon Cognito 使用者集區來設定 AWS AppSync API。

  1. 選擇 Settings (設定) 標籤。

  2. Authorization Type (授權類型) 區段下,選擇 Amazon Cognito User Pool (Amazon Cognito 使用者集區)

  3. 使用者集區組態 下,為區域 選擇 US-WEST-2AWS

  4. 選擇 AppSyncTutorial- UserPool使用者集區。

  5. 選擇 DENY作為預設動作

  6. AppId 用戶端 regex 欄位保留空白。

  7. 選擇 Save (儲存)。

API 現已設定為使用 Amazon Cognito 使用者集區作為其授權類型。

設定 DynamoDB 資料表的資料來源

建立 DynamoDB 資料表後,請在主控台API中導覽至 AWS AppSync GraphQL,然後選擇資料來源索引標籤。現在,您要 AWS AppSync 為您剛建立的每個 DynamoDB 資料表在 中建立資料來源。

  1. 選擇 Data source (資料來源) 標籤。

  2. 選擇 New (新建) 來建立新資料來源。

  3. 輸入 PicturesDynamoDBTable 做為資料來源名稱。

  4. 選擇 Amazon DynamoDB table (Amazon DynamoDB 資料表) 做為資料來源類型。

  5. 針對區域,選擇 US-WEST-2

  6. 從資料表清單中,選擇 AppSyncTutorial-Pictures DynamoDB 資料表。

  7. 建立或使用現有角色區段中,選擇現有角色

  8. 選擇剛從 CloudFormation 範本建立的角色。如果您未變更 ResourceNamePrefix,角色的名稱應為 AppSyncTutorial-D ynamoDBRole

  9. 選擇 Create (建立)。

針對朋友資料表重複相同的程序,如果您在建立 CloudFormation 堆疊時未變更 ResourceNamePrefix 參數,則 DynamoDB 資料表的名稱應為 AppSyncTutorial- 朋友

建立 GraphQL 結構描述

現在資料來源已連接至 DynamoDB 資料表,讓我們建立 GraphQL 結構描述。從 AWS AppSync 主控台的結構描述編輯器中,確保您的結構描述符合下列結構描述:

schema { query: Query mutation: Mutation } type Mutation { createPicture(input: CreatePictureInput!): Picture! @aws_auth(cognito_groups: ["Admins"]) createFriendship(id: ID!, target: ID!): Boolean @aws_auth(cognito_groups: ["Admins"]) } type Query { getPicturesByOwner(id: ID!): [Picture] @aws_auth(cognito_groups: ["Admins", "Viewers"]) } type Picture { id: ID! owner: ID! src: String } input CreatePictureInput { owner: ID! src: String! }

選擇 Save Schema (儲存結構描述) 來儲存結構描述。

有些結構描述欄位已標註 @aws_auth 指令。由於API預設動作組態設定為 DENY,因此 會API拒絕不是 @aws_auth 指令中提及群組成員的所有使用者。如需有關如何保護 的詳細資訊API,請參閱安全頁面。在此情況下,只有管理員使用者可以存取 Mutation.createPictureMutation.createFriendship 欄位,而管理員檢視器群組的成員使用者可以存取 Query.getPicturesByOwner 欄位。其他所有使用者都無存取權。

設定解析程式

現在,您已備妥有效的 GraphQL 結構描述和兩個資料來源,您可以將解析程式連接到結構描述上的 GraphQL 欄位。API 提供下列功能:

  • 透過 Mutation 欄位建立圖片。createPicture

  • 透過 Mutation 欄位建立友誼。createFriendship

  • 透過查詢欄位擷取圖片。getPicture

突變。createPicture

從 AWS AppSync 主控台的結構描述編輯器中,在右側選擇連接解析程式createPicture(input: CreatePictureInput!): Picture!。選擇 DynamoDBPicturesDynamoDBTable 資料來源。在 request mapping template (要求映射範本) 區段中,新增下列範本:

#set($id = $util.autoId()) { "version" : "2018-05-29", "operation" : "PutItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($id), "owner": $util.dynamodb.toDynamoDBJson($ctx.args.input.owner) }, "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args.input) }

response mapping template (回應映射範本) 區段中,新增下列範本:

#if($ctx.error) $util.error($ctx.error.message, $ctx.error.type) #end $util.toJson($ctx.result)

建立圖片功能完成。您要將圖片儲存在圖片表中,使用隨機產生的圖片 ID,並使用 Cognito UUID 使用者名稱作為圖片的擁有者。

突變。createFriendship

從 AWS AppSync 主控台的結構描述編輯器中,選擇適用於 的連接解析程式createFriendship(id: ID!, target: ID!): Boolean。選擇 DynamoDBFriendsDynamoDBTable 資料來源。在 request mapping template (要求映射範本) 區段中,新增下列範本:

#set($userToFriendFriendship = { "userId" : "$ctx.args.id", "friendId": "$ctx.args.target" }) #set($friendToUserFriendship = { "userId" : "$ctx.args.target", "friendId": "$ctx.args.id" }) #set($friendsItems = [$util.dynamodb.toMapValues($userToFriendFriendship), $util.dynamodb.toMapValues($friendToUserFriendship)]) { "version" : "2018-05-29", "operation" : "BatchPutItem", "tables" : { ## Replace 'AppSyncTutorial-' default below with the ResourceNamePrefix you provided in the CloudFormation template "AppSyncTutorial-Friends": $util.toJson($friendsItems) } }

重要:在BatchPutItem請求範本中,DynamoDB 資料表的確切名稱應存在。預設資料表名稱為 AppSyncTutorial- 朋友 。如果您使用的資料表名稱錯誤, AppSync 嘗試擔任提供的角色時,會出現錯誤。

為了本教學課程的簡單性,請繼續執行,如同友誼請求已核准一樣,並將關係項目直接儲存至AppSyncTutorialFriends資料表中。

很快地,您就能為每個朋友關係儲存兩個項目,做為雙向關係。如需 Amazon DynamoDB 表示 many-to-many關係的最佳實務的詳細資訊,請參閱 DynamoDB 最佳實務

response mapping template (回應映射範本) 區段中,新增下列範本:

#if($ctx.error) $util.error($ctx.error.message, $ctx.error.type) #end true

注意:請確定您的要求範本包含適當的資料表名稱。預設名稱為 AppSyncTutorial- 朋友 ,但如果您變更 參數, CloudFormation ResourceNamePrefix資料表名稱可能會有所不同。

Query.getPicturesByOwner

現在您已經備妥朋友關係和圖片,您還需要提供讓使用者檢視其朋友圖片的權限。為了滿足這項要求,您必須先檢查申請者是內容擁有者的朋友,最後提供圖片查詢功能。

由於此功能需要兩個資料來源操作,所以您要建立兩個函數。第一個函數 會isFriend檢查請求者和擁有者是否為朋友。第二個函數getPicturesBy擁有者 會擷取指定擁有者 ID 的請求圖片。讓我們來看看 Query.getPicturesByOwner 欄位上提議解析器的執行流程:

  1. Before 映射範本:準備內容和欄位輸入引數。

  2. isFriend 函數:檢查請求者是否為圖片的擁有者。如果不是,它會透過在朋友資料表上執行 DynamoDB GetItem 操作,檢查請求者和擁有者使用者是否為朋友。

  3. getPicturesBy擁有者函數:使用擁有者索引全域次要索引上的 DynamoDB 查詢操作,從圖片資料表擷取圖片。

  4. After 映射範本:映射圖片結果,讓 DynamoDB 屬性正確映射到預期的 GraphQL 類型欄位。

首先,讓我們來建立下列函數。

isFriend 函數
  1. 選擇 Functions (函數) 索引標籤。

  2. 選擇 Create Function (建立函數) 來建立函數。

  3. 輸入 FriendsDynamoDBTable 做為資料來源名稱。

  4. 對於函數名稱,輸入 isFriend

  5. 在要求映射範本文字區域中,貼上下列範本:

    #set($ownerId = $ctx.prev.result.owner) #set($callerId = $ctx.prev.result.callerId) ## if the owner is the caller, no need to make the check #if($ownerId == $callerId) #return($ctx.prev.result) #end { "version" : "2018-05-29", "operation" : "GetItem", "key" : { "userId" : $util.dynamodb.toDynamoDBJson($callerId), "friendId" : $util.dynamodb.toDynamoDBJson($ownerId) } }
  6. 在回應映射範本文字區域中,貼上下列範本:

    #if($ctx.error) $util.error("Unable to retrieve friend mapping message: ${ctx.error.message}", $ctx.error.type) #end ## if the users aren't friends #if(!$ctx.result) $util.unauthorized() #end $util.toJson($ctx.prev.result)
  7. 選擇 Create Function (建立函數)

結果:您已建立isFriend函數。

getPicturesBy擁有者函數
  1. 選擇 Functions (函數) 索引標籤。

  2. 選擇 Create Function (建立函數) 來建立函數。

  3. 輸入 PicturesDynamoDBTable 做為資料來源名稱。

  4. 對於函數名稱,輸入 getPicturesByOwner

  5. 在要求映射範本文字區域中,貼上下列範本:

    { "version" : "2018-05-29", "operation" : "Query", "query" : { "expression": "#owner = :owner", "expressionNames": { "#owner" : "owner" }, "expressionValues" : { ":owner" : $util.dynamodb.toDynamoDBJson($ctx.prev.result.owner) } }, "index": "owner-index" }
  6. 在回應映射範本文字區域中,貼上下列範本:

    #if($ctx.error) $util.error($ctx.error.message, $ctx.error.type) #end $util.toJson($ctx.result)
  7. 選擇 Create Function (建立函數)

結果:您已建立getPicturesBy擁有者函數。現在已建立函數,請將管道解析程式連接至 Query.getPicturesByOwner 欄位。

從 AWS AppSync 主控台的結構描述編輯器中,選擇連接解析程式Query.getPicturesByOwner(id: ID!): [Picture]在接下來的頁面,選擇會出現在資料來源下拉式清單中的 Convert to pipeline resolver (轉換成管道解析程式) 連結。使用下列程序來使用 Before 映射範本:

#set($result = { "owner": $ctx.args.id, "callerId": $ctx.identity.username }) $util.toJson($result)

after mapping template (After 映射範本) 區段中,使用下列範本:

#foreach($picture in $ctx.result.items) ## prepend "src://" to picture.src property #set($picture['src'] = "src://${picture['src']}") #end $util.toJson($ctx.result.items)

選擇 Create Resolver (建立解析程式)。您已成功連接第一個管道解析程式。在相同頁面上,新增您之前建立的兩個函數。在函數區段中,選擇新增函數,然後選擇或輸入第一個函數的名稱 isFriend。按照getPicturesBy擁有者函數的相同程序新增第二個函數。請確定isFriend函數先出現在清單中,然後是getPicturesBy擁有者函數。您可以使用上下箭頭,重新安排管道中的函數執行順序。

現在管道解析程式已建立且您已連接函數,讓我們測試新建立的 GraphQL API。

測試您的 GraphQL API

首先,您必須透過您先前建立的管理員使用者,執行少量變動來填入圖片和朋友關係。在 AWS AppSync 主控台左側,選擇查詢索引標籤。

createPicture 突變

  1. 在 AWS AppSync 主控台中,選擇查詢索引標籤。

  2. 選擇 Login With User Pools (登入使用者集區)

  3. 在模型上,輸入 CloudFormation 堆疊建立的 Cognito 範例用戶端 ID,例如 37solo6mmhh7k4v63cqdfgdg5d)。

  4. 輸入您作為 參數傳遞至 CloudFormation 堆疊的使用者名稱。預設為 nadia

  5. 使用傳送給您作為 CloudFormation 堆疊參數提供的電子郵件的臨時密碼 (例如 UserPoolUserEmail)。

  6. 選擇 Login (登入)。您現在應該會看到重新命名為 Logout nadia 的按鈕,或您在建立 CloudFormation 堆疊時選擇的任何使用者名稱 (即 UserPoolUsername)。

讓我們傳送一些createPicture突變來填入圖片表。在主控台中,執行以下 GraphQL 查詢:

mutation { createPicture(input:{ owner: "nadia" src: "nadia.jpg" }) { id owner src } }

回應看起來應如下所示:

{ "data": { "createPicture": { "id": "c6fedbbe-57ad-4da3-860a-ffe8d039882a", "owner": "nadia", "src": "nadia.jpg" } } }

讓我們新增更多圖片:

mutation { createPicture(input:{ owner: "shaggy" src: "shaggy.jpg" }) { id owner src } }
mutation { createPicture(input:{ owner: "rex" src: "rex.jpg" }) { id owner src } }

您已透過管理使用者的身分,使用 nadia 新增三張圖片。

createFriendship 突變

讓我們來新增朋友關係項目。在主控台中,執行下列變動。

注意:您仍必須登入管理使用者 (預設管理使用者是 nadia)。

mutation { createFriendship(id: "nadia", target: "shaggy") }

回應看起來應該會像這樣:

{ "data": { "createFriendship": true } }

nadiashaggy 是朋友。rex 不是任何人的朋友。

getPicturesBy擁有者查詢

第一步是使用 Cognito 使用者集區,以及本教學課程一開始所設定的登入資料,登入成為 nadia 使用者。登入為 nadia 時,擷取 shaggy 擁有的圖片。

query { getPicturesByOwner(id: "shaggy") { id owner src } }

由於 nadiashaggy 是朋友,所以查詢應該會傳回相對應的圖片。

{ "data": { "getPicturesByOwner": [ { "id": "05a16fba-cc29-41ee-a8d5-4e791f4f1079", "owner": "shaggy", "src": "src://shaggy.jpg" } ] } }

同樣地,嘗試擷取自己圖片的 nadia 也能順利擷取。管道解析程式已最佳化,以避免在這種情況下執行isFriend GetItem 操作。嘗試下列查詢:

query { getPicturesByOwner(id: "nadia") { id owner src } }

如果您在 API(在設定窗格中) 上啟用記錄,請將偵錯層級設定為 ALL,然後再次執行相同的查詢,則會傳回欄位執行的日誌。透過查看日誌,您可以判斷isFriend函數是否在請求映射範本階段提早傳回:

{ "errors": [], "mappingTemplateType": "Request Mapping", "path": "[getPicturesByOwner]", "resolverArn": "arn:aws:appsync:us-west-2:XXXX:apis/XXXX/types/Query/fields/getPicturesByOwner", "functionArn": "arn:aws:appsync:us-west-2:XXXX:apis/XXXX/functions/o2f42p2jrfdl3dw7s6xub2csdfs", "functionName": "isFriend", "earlyReturnedValue": { "owner": "nadia", "callerId": "nadia" }, "context": { "arguments": { "id": "nadia" }, "prev": { "result": { "owner": "nadia", "callerId": "nadia" } }, "stash": {}, "outErrors": [] }, "fieldInError": false }

earlyReturnedValue 金鑰代表 #return 指令傳回的資料。

最後,即使 rexViewers Cognito UserPool 群組的成員,而且由於 rex 不是任何人的朋友,他將無法存取任何由晃動nadia 擁有的圖片。如果您以 rex 登入主控台,並執行下列查詢時:

query { getPicturesByOwner(id: "nadia") { id owner src } }

您會收到下列關於未經授權的錯誤:

{ "data": { "getPicturesByOwner": null }, "errors": [ { "path": [ "getPicturesByOwner" ], "data": null, "errorType": "Unauthorized", "errorInfo": null, "locations": [ { "line": 2, "column": 9, "sourceName": null } ], "message": "Not Authorized to access getPicturesByOwner on type Query" } ] }

這表示您已成功使用管道解析程式,實作複雜的授權程序。