使用 DynamoDB JavaScript 解析程式建立簡單的後期應用程式 - AWS AppSync

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

使用 DynamoDB JavaScript 解析程式建立簡單的後期應用程式

在本教學課程中,您將匯入 Amazon DynamoDB 資料表至 AWS AppSync ,並使用管道API JavaScript 解析器來建立全功能 GraphQL,您可以在自己的應用程式中使用。

您將使用 AWS AppSync 主控台佈建 Amazon DynamoDB 資源、建立解析器,並將其連接至資料來源。您也可以透過 GraphQL 陳述式讀取和寫入 Amazon DynamoDB 資料庫,並訂閱即時資料。

必須完成特定步驟,才能將 GraphQL 陳述式轉換為 Amazon DynamoDB 操作,並將回應轉換回 GraphQL 。本教學課程概述透過幾個真實世界案例和資料存取模式的組態程序。

建立 GraphQL API

若要在 API中建立 GraphQL AWS AppSync

  1. 開啟 AppSync 主控台,然後選擇建立 API

  2. 從頭選取設計,然後選擇下一步。

  3. 為您的 API 命名PostTutorialAPI,然後選擇下一個 。跳至檢閱頁面,同時將其餘選項設定為其預設值,然後選擇 Create

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

定義基本文章 API

現在您已擁有 GraphQL API,您可以設定基本結構描述,以允許基本建立、擷取和刪除貼文資料。

將資料新增至您的結構描述

  1. 在 中API,選擇結構描述索引標籤。

  2. 我們將建立結構描述,以定義Post類型和addPost新增和取得Post物件的操作。在結構描述窗格中,使用下列程式碼取代內容:

    schema { query: Query mutation: Mutation } type Query { getPost(id: ID): Post } type Mutation { addPost( id: ID! author: String! title: String! content: String! url: String! ): Post! } type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! }
  3. 選擇 Save Schema (儲存結構描述)

設定 Amazon DynamoDB 資料表

AWS AppSync 主控台可協助佈建所需的 AWS 資源,以將您自己的資源存放在 Amazon DynamoDB 資料表中。在此步驟中,您將建立 Amazon DynamoDB 資料表來儲存您的文章。您也會設定次要索引,稍後再使用。

若要建立 Amazon DynamoDB 資料表

  1. 結構描述頁面上,選擇建立資源

  2. 選擇使用現有類型 ,然後選擇Post類型。

  3. 其他索引區段中,選擇新增索引

  4. 為索引命名 author-index

  5. Primary key 設定為 author,將 Sort金鑰設定為 None

  6. 停用自動產生 GraphQL 。在此範例中,我們將自行建立解析程式。

  7. 選擇 Create (建立)。

您現在有名為 的新資料來源PostTable,您可以前往側邊標籤中的資料來源查看。您將使用此資料來源將查詢和突變連結至您的 Amazon DynamoDB 資料表。

設定 addPost 解析程式 (Amazon DynamoDB PutItem)

現在 AWS AppSync 已了解 Amazon DynamoDB 資料表,您可以透過定義解析器將其連結至個別查詢和突變。您建立的第一個解析程式是使用 的addPost管道解析程式 JavaScript,可讓您在 Amazon DynamoDB 資料表中建立文章。管道解析程式具有下列元件:

  • 在 GraphQL 結構描述中要附加解析程式的位置。在這種情況下,您會對 createPost 類型上的 Mutation 欄位設定解析程式。當呼叫者呼叫突變 時,會叫用此解析器{ addPost(...){...} }

  • 用於此解析程式的資料來源。在此情況下,您想要使用先前定義的 DynamoDB 資料來源,以便您可以將項目新增至 post-table-for-tutorial DynamoDB 資料表。

  • 請求處理常式。請求處理常式是處理來自呼叫者傳入請求的函數,並將其轉換為 的指示 AWS AppSync ,以針對 DynamoDB 執行 。

  • 回應處理常式。回應處理常式的任務是處理來自 DynamoDB 的回應,並將其轉換回 GraphQL 預期的內容。如果 DynamoDB 中的資料形狀與 GraphQL 中的 Post 類型不同,此功能會很有用,但如果他們的形狀一樣,您只需傳遞資料。

設定解析器

  1. 在 中API,選擇結構描述索引標籤。

  2. 解析程式窗格中,尋找Mutation類型下方的addPost欄位,然後選擇連接

  3. 選擇您的資料來源,然後選擇建立

  4. 在程式碼編輯器中,使用此程式碼片段取代程式碼:

    import { util } from '@aws-appsync/utils' import * as ddb from '@aws-appsync/utils/dynamodb' export function request(ctx) { const item = { ...ctx.arguments, ups: 1, downs: 0, version: 1 } const key = { id: ctx.args.id ?? util.autoId() } return ddb.put({ key, item }) } export function response(ctx) { return ctx.result }
  5. 選擇 Save (儲存)。

注意

在此程式碼中,您可以使用 DynamoDB 模組 utils,讓您輕鬆地建立 DynamoDB 請求。

AWS AppSync 隨附名為 的自動 ID 產生公用程式util.autoId(),用於產生新文章的 ID。如果您未指定 ID,則公用程式會自動為您產生 ID。

const key = { id: ctx.args.id ?? util.autoId() }

如需適用於 的公用程式的詳細資訊 JavaScript,請參閱 JavaScript 解析器和函數的執行期功能

呼叫 API以新增文章

現在已設定解析器, AWS AppSync 可以將傳入addPost的突變轉譯為 Amazon DynamoDB PutItem操作。您現在可以執行變動以將項目放置到資料表中。

執行操作

  1. 在 中API,選擇查詢索引標籤。

  2. 查詢窗格中,新增下列突變:

    mutation addPost { addPost( id: 123, author: "AUTHORNAME" title: "Our first post!" content: "This is our first post." url: "https://aws.amazon.com/appsync/" ) { id author title content url ups downs version } }
  3. 選擇執行 (橘色播放按鈕),然後選擇 addPost。新建立的文章結果應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:

    { "data": { "addPost": { "id": "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }

下列說明顯示發生的情況:

  1. AWS AppSync 收到addPost突變請求。

  2. AWS AppSync 會執行解析程式的請求處理常式。ddb.put 函數會建立如下所示的PutItem請求:

    { operation: 'PutItem', key: { id: { S: '123' } }, attributeValues: { downs: { N: 0 }, author: { S: 'AUTHORNAME' }, ups: { N: 1 }, title: { S: 'Our first post!' }, version: { N: 1 }, content: { S: 'This is our first post.' }, url: { S: 'https://aws.amazon.com/appsync/' } } }
  3. AWS AppSync 使用此值來產生和執行 Amazon DynamoDB PutItem請求。

  4. AWS AppSync 取得PutItem請求的結果並將其轉換回 GraphQL 類型。

    { "id" : "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups" : 1, "downs" : 0, "version" : 1 }
  5. 回應處理常式會立即傳回結果 (return ctx.result)。

  6. 最終結果會顯示在 GraphQL 回應中。

設定 getPost 解析程式 (Amazon DynamoDB GetItem)

現在您可以將資料新增至 Amazon DynamoDB 資料表,您需要設定getPost查詢,以便從資料表擷取該資料。若要執行此作業,您可以設定另一個解析程式。

若要新增您的解析器

  1. 在 中API,選擇結構描述索引標籤。

  2. 在右側解析程式窗格中,尋找 Query 類型上的getPost欄位,然後選擇連接

  3. 選擇您的資料來源,然後選擇建立

  4. 在程式碼編輯器中,使用此程式碼片段取代程式碼:

    import * as ddb from '@aws-appsync/utils/dynamodb' export function request(ctx) { return ddb.get({ key: { id: ctx.args.id } }) } export const response = (ctx) => ctx.result
  5. 儲存您的解析程式。

注意

在此解析程式中,我們使用回應處理常式的箭頭函數表達式。

呼叫 API以取得文章

現在已設定解析器, AWS AppSync 知道如何將傳入的getPost查詢轉換為 Amazon DynamoDB GetItem操作。您現在可以執行查詢,擷取您稍早建立的貼文。

執行查詢

  1. 在 中API,選擇查詢索引標籤。

  2. 查詢窗格中,新增下列程式碼,並使用您在建立文章後複製的 ID:

    query getPost { getPost(id: "123") { id author title content url ups downs version } }
  3. 選擇執行 (橘色播放按鈕),然後選擇 getPost。新建立的文章結果應出現在查詢窗格右側的結果窗格中。

  4. 從 Amazon DynamoDB 擷取的文章應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:

    { "data": { "getPost": { "id": "123", "author": "AUTHORNAME", "title": "Our first post!", "content": "This is our first post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }

或者,採取下列範例:

query getPost { getPost(id: "123") { id author title } }

如果您的getPost查詢只需要 idauthortitle,您可以變更請求函數以使用投影表達式,以僅指定您想要從 DynamoDB 資料表傳輸到 的屬性,以避免不必要的資料從 DynamoDB 傳輸到 AWS AppSync。例如,請求函數可能看起來像下面的程式碼片段:

import * as ddb from '@aws-appsync/utils/dynamodb' export function request(ctx) { return ddb.get({ key: { id: ctx.args.id }, projection: ['author', 'id', 'title'], }) } export const response = (ctx) => ctx.result

您也可以使用 selectionSetList搭配 getPost 來代表 expression

import * as ddb from '@aws-appsync/utils/dynamodb' export function request(ctx) { const projection = ctx.info.selectionSetList.map((field) => field.replace('/', '.')) return ddb.get({ key: { id: ctx.args.id }, projection }) } export const response = (ctx) => ctx.result

建立 updatePost 突變 (Amazon DynamoDB UpdateItem)

到目前為止,您可以在 Amazon DynamoDB 中建立和擷取Post物件。接下來,您將設定新的突變來更新物件。與需要指定所有欄位的addPost突變相比,此突變只允許您指定要變更的欄位。它還引入了新的expectedVersion引數,允許您指定要修改的版本。您將設定條件,以確保您正在修改物件的最新版本。您將使用 UpdateItem Amazon DynamoDB https://operation.sc

更新解析器

  1. 在 中API,選擇結構描述索引標籤。

  2. 修改 Schema (結構描述) 窗格中的 Mutation 類型來新增 updatePost 變動,如下所示:

    type Mutation { updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( id: ID author: String! title: String! content: String! url: String! ): Post! }
  3. 選擇 Save Schema (儲存結構描述)

  4. 在右側的解析程式窗格中,尋找Mutation類型上新建立updatePost的欄位,然後選擇連接 。使用以下程式碼片段建立新的解析程式:

    import { util } from '@aws-appsync/utils'; import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const { id, expectedVersion, ...rest } = ctx.args; const values = Object.entries(rest).reduce((obj, [key, value]) => { obj[key] = value ?? ddb.operations.remove(); return obj; }, {}); return ddb.update({ key: { id }, condition: { version: { eq: expectedVersion } }, update: { ...values, version: ddb.operations.increment(1) }, }); } export function response(ctx) { const { error, result } = ctx; if (error) { util.appendError(error.message, error.type); } return result;
  5. 儲存您所做的任何變更。

此解析器會使用 ddb.update來建立 Amazon DynamoDB UpdateItem請求。您只是要求 Amazon DynamoDB 更新特定屬性,而不是撰寫整個項目。這是使用 Amazon DynamoDB 更新表達式完成的。

ddb.update 函數會將金鑰和更新物件作為引數。然後,檢查傳入引數的值。當值設定為 時null,請使用 DynamoDB remove操作來表示該值應該從 DynamoDB 項目中移除。

也有新的condition區段。條件表達式可讓您在執行操作之前,根據 Amazon DynamoDB 中已存在的物件狀態,告知 AWS AppSync 和 Amazon DynamoDB 請求是否應成功。在此情況下,只有當 Amazon DynamoDB 中目前項目version的欄位完全符合expectedVersion引數時,您才希望UpdateItem請求成功。項目更新時,我們希望增加 的值version。操作函數 很容易做到這一點increment

如需條件表達式的詳細資訊,請參閱條件表達式文件。

如需UpdateItem請求的詳細資訊,請參閱 UpdateItem 文件和 DynamoDB 模組文件。

如需如何寫入更新表達式的詳細資訊,請參閱 DynamoDB UpdateExpressions 文件。

呼叫 API以更新文章

讓我們嘗試使用新的解析器更新Post物件。

更新物件

  1. 在 中API,選擇查詢索引標籤。

  2. 查詢窗格中,新增下列突變。您還需要將id引數更新為您先前記下的值:

    mutation updatePost { updatePost( id:123 title: "An empty story" content: null expectedVersion: 1 ) { id author title content url ups downs version } }
  3. 選擇執行 (橘色播放按鈕),然後選擇 updatePost

  4. Amazon DynamoDB 中更新的文章應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:

    { "data": { "updatePost": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 2 } } }

在此請求中,您要求 AWS AppSync 和 Amazon DynamoDB 僅更新 titlecontent 欄位。所有其他欄位都是單獨保留的 (除了增加version欄位)。您可以將 title 屬性設定為新值,並從文章中移除 content 屬性。authorurlupsdowns 欄位維持原狀。嘗試再次執行突變請求,同時保持請求的原樣。您應該會看到類似以下的回應:

{ "data": { "updatePost": null }, "errors": [ { "path": [ "updatePost" ], "data": null, "errorType": "DynamoDB:ConditionalCheckFailedException", "errorInfo": null, "locations": [ { "line": 2, "column": 3, "sourceName": null } ], "message": "The conditional request failed (Service: DynamoDb, Status Code: 400, Request ID: 1RR3QN5F35CS8IV5VR4OQO9NNBVV4KQNSO5AEMVJF66Q9ASUAAJG)" } ] }

請求失敗,因為條件表達式評估為false

  1. 第一次執行請求時,Amazon DynamoDB 中文章version的欄位值為 1,符合引expectedVersion數。請求成功,這表示 version 欄位已在 Amazon DynamoDB 中遞增至 2

  2. 第二次執行請求時,Amazon DynamoDB 中文章version的欄位值為 2,這與expectedVersion引數不相符。

此模式通常稱為樂觀鎖定

建立投票突變 (Amazon DynamoDB UpdateItem)

Post 類型包含 upsdowns 欄位,以啟用向上和向下記錄。不過,目前 API不會讓我們對它們進行任何動作。讓我們新增突變,讓我們向上和向下移動文章。

新增您的突變

  1. 在 中API,選擇結構描述索引標籤。

  2. 結構描述窗格中,修改Mutation類型並新增DIRECTION列舉以新增新的投票突變:

    type Mutation { vote(id: ID!, direction: DIRECTION!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( id: ID, author: String!, title: String!, content: String!, url: String! ): Post! } enum DIRECTION { UP DOWN }
  3. 選擇 Save Schema (儲存結構描述)

  4. 在右側的解析程式窗格中,尋找Mutation類型上新建立vote的欄位,然後選擇連接 。透過建立和將程式碼取代為下列程式碼片段來建立新的解析程式:

    import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const field = ctx.args.direction === 'UP' ? 'ups' : 'downs'; return ddb.update({ key: { id: ctx.args.id }, update: { [field]: ddb.operations.increment(1), version: ddb.operations.increment(1), }, }); } export const response = (ctx) => ctx.result;
  5. 儲存您所做的任何變更。

呼叫 API以向上或向下移動文章

現在已設定新的解析程式, AWS AppSync 知道如何將傳入upvotePostdownvote突變轉譯為 Amazon DynamoDB UpdateItem操作。您現在可以執行變動,對您之前建立的文章表達贊同或不贊同。

執行您的突變

  1. 在 中API,選擇查詢索引標籤。

  2. 查詢窗格中,新增下列突變。您還需要將id引數更新為您先前記下的值:

    mutation votePost { vote(id:123, direction: UP) { id author title content url ups downs version } }
  3. 選擇執行 (橘色播放按鈕),然後選擇 votePost

  4. Amazon DynamoDB 中更新的文章應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:

    { "data": { "vote": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 6, "downs": 0, "version": 4 } } }
  5. 選擇再執行幾次。每次執行查詢1時,您應該會看到 upsversion 欄位遞增。

  6. 變更查詢以使用不同的 呼叫它DIRECTION

    mutation votePost { vote(id:123, direction: DOWN) { id author title content url ups downs version } }
  7. 選擇執行 (橘色播放按鈕),然後選擇 votePost

    這次,您應該會看到 1 downsversion 欄位在每次執行查詢時遞增。

設定 deletePost 解析程式 (Amazon DynamoDB DeleteItem)

接下來,您會想要建立突變來刪除文章。您將使用 Amazon DynamoDB DeleteItem 操作來執行此操作。

新增您的突變

  1. 在結構描述中,選擇結構描述索引標籤。

  2. 結構描述窗格中,修改Mutation類型以新增新deletePost突變:

    type Mutation { deletePost(id: ID!, expectedVersion: Int): Post vote(id: ID!, direction: DIRECTION!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( id: ID author: String!, title: String!, content: String!, url: String! ): Post! }
  3. 這次,您將 expectedVersion 欄位設為選用。接下來,選擇儲存結構描述

  4. 在右側的解析程式窗格中,尋找Mutation類型中新建立delete的欄位,然後選擇連接 。使用下列程式碼建立新的解析器:

    import { util } from '@aws-appsync/utils' import { util } from '@aws-appsync/utils'; import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { let condition = null; if (ctx.args.expectedVersion) { condition = { or: [ { id: { attributeExists: false } }, { version: { eq: ctx.args.expectedVersion } }, ], }; } return ddb.remove({ key: { id: ctx.args.id }, condition }); } export function response(ctx) { const { error, result } = ctx; if (error) { util.appendError(error.message, error.type); } return result; }
    注意

    expectedVersion 引數是選用的引數。如果呼叫者在請求中設定expectedVersion引數,則請求處理常式會新增一個條件,只有在項目已刪除,或 Amazon DynamoDB 中文章的version屬性完全符合 時,才會允許DeleteItem請求成功expectedVersion。如果省略,將不會在 DeleteItem 要求中指定條件表達式。無論 的值為何version,或該項目是否存在 Amazon DynamoDB 中,它都會成功。

    即使您要刪除項目,如果該項目尚未刪除,您也可以傳回已刪除的項目。

如需DeleteItem請求的詳細資訊,請參閱 DeleteItem 文件。

呼叫 API以刪除文章

現在,解析程式已設定完成, AWS AppSync 知道如何將傳入delete的突變轉換為 Amazon DynamoDB DeleteItem操作。您現在可以執行變動以在資料表中刪除項目。

執行您的突變

  1. 在 中API,選擇查詢索引標籤。

  2. 查詢窗格中,新增下列突變。您還需要將id引數更新為您先前記下的值:

    mutation deletePost { deletePost(id:123) { id author title content url ups downs version } }
  3. 選擇執行 (橘色播放按鈕),然後選擇 deletePost

  4. 文章會從 Amazon DynamoDB 中刪除。請注意, 會 AWS AppSync 傳回從 Amazon DynamoDB 刪除的項目值,該值應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:

    { "data": { "deletePost": { "id": "123", "author": "A new author", "title": "An empty story", "content": null, "url": "https://aws.amazon.com/appsync/", "ups": 6, "downs": 4, "version": 12 } } }
  5. 只有在此呼叫deletePost是實際從 Amazon DynamoDB 刪除的值時,才會傳回該值。再次選擇執行

  6. 呼叫仍然成功,但不會傳回任何值:

    { "data": { "deletePost": null } }
  7. 現在,讓我們嘗試刪除文章,但這次會指定 expectedValue。首先,您需要建立新的文章,因為您剛刪除了目前為止使用過的文章。

  8. 查詢窗格中,新增下列突變:

    mutation addPost { addPost( id:123 author: "AUTHORNAME" title: "Our second post!" content: "A new post." url: "https://aws.amazon.com/appsync/" ) { id author title content url ups downs version } }
  9. 選擇執行 (橘色播放按鈕),然後選擇 addPost

  10. 新建立的文章結果應出現在查詢窗格右側的結果窗格中。記錄新建立物件id的 ,因為您只需要一點時間即可完成。其看起來與下列類似:

    { "data": { "addPost": { "id": "123", "author": "AUTHORNAME", "title": "Our second post!", "content": "A new post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }
  11. 現在,讓我們嘗試刪除具有 非法值的文章expectedVersion。在查詢窗格中,新增下列突變。您還需要將id引數更新為您先前記下的值:

    mutation deletePost { deletePost( id:123 expectedVersion: 9999 ) { id author title content url ups downs version } }
  12. 選擇執行 (橘色播放按鈕),然後選擇 deletePost。傳回下列結果:

    { "data": { "deletePost": null }, "errors": [ { "path": [ "deletePost" ], "data": null, "errorType": "DynamoDB:ConditionalCheckFailedException", "errorInfo": null, "locations": [ { "line": 2, "column": 3, "sourceName": null } ], "message": "The conditional request failed (Service: DynamoDb, Status Code: 400, Request ID: 7083O037M1FTFRK038A4CI9H43VV4KQNSO5AEMVJF66Q9ASUAAJG)" } ] }
  13. 請求失敗,因為條件表達式評估為 false。Amazon DynamoDB 中version帖子的值與引數中expectedValue指定的值不相符。會在 GraphQL 回應 data 區段中 errors 欄位傳回物件的目前值。重試要求,但更正 expectedVersion

    mutation deletePost { deletePost( id:123 expectedVersion: 1 ) { id author title content url ups downs version } }
  14. 選擇執行 (橘色播放按鈕),然後選擇 deletePost

    這次請求成功,並傳回從 Amazon DynamoDB 刪除的值:

    { "data": { "deletePost": { "id": "123", "author": "AUTHORNAME", "title": "Our second post!", "content": "A new post.", "url": "https://aws.amazon.com/appsync/", "ups": 1, "downs": 0, "version": 1 } } }
  15. 再次選擇執行。呼叫仍然成功,但這次不會傳回任何值,因為文章已在 Amazon DynamoDB 中刪除。

    { "data": { "deletePost": null } }

設定 allPost 解析程式 (Amazon DynamoDB Scan)

目前為止,只有在您知道要查看的每個文章id的 API 時才有用。讓我們新增新的解析程式,傳回資料表中的所有文章。

新增您的突變

  1. 在 中API,選擇結構描述索引標籤。

  2. 修改 Schema (結構描述) 窗格中的 Query 類型以新增 allPost 查詢,如下所示:

    type Query { allPost(limit: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
  3. 新增 PaginationPosts 類型:

    type PaginatedPosts { posts: [Post!]! nextToken: String }
  4. 選擇 Save Schema (儲存結構描述)

  5. 在右側的解析程式窗格中,尋找Query類型中新建立allPost的欄位,然後選擇連接 。使用下列程式碼建立新的解析器:

    import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const { limit = 20, nextToken } = ctx.arguments; return ddb.scan({ limit, nextToken }); } export function response(ctx) { const { items: posts = [], nextToken } = ctx.result; return { posts, nextToken }; }

    此解析程式的請求處理常式預期有兩個選用引數:

    • limit - 指定在單一呼叫中傳回的項目數量上限。

    • nextToken - 用於擷取下一組結果 (我們將顯示 的值nextToken來自稍後的位置)。

  6. 儲存對解析器所做的任何變更。

如需Scan請求的詳細資訊,請參閱掃描參考文件。

呼叫 API以掃描所有文章

現在已設定解析器, AWS AppSync 知道如何將傳入的allPost查詢轉換為 Amazon DynamoDB Scan操作。您現在可以掃描資料表來擷取所有文章。在您可以嘗試之前,您必須將一些資料填入資料表,因為您已刪除目前為止所使用的項目。

新增和查詢資料

  1. 在 中API,選擇查詢索引標籤。

  2. 查詢窗格中,新增下列突變:

    mutation addPost { post1: addPost(id:1 author: "AUTHORNAME" title: "A series of posts, Volume 1" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post2: addPost(id:2 author: "AUTHORNAME" title: "A series of posts, Volume 2" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post3: addPost(id:3 author: "AUTHORNAME" title: "A series of posts, Volume 3" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post4: addPost(id:4 author: "AUTHORNAME" title: "A series of posts, Volume 4" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post5: addPost(id:5 author: "AUTHORNAME" title: "A series of posts, Volume 5" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post6: addPost(id:6 author: "AUTHORNAME" title: "A series of posts, Volume 6" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post7: addPost(id:7 author: "AUTHORNAME" title: "A series of posts, Volume 7" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post8: addPost(id:8 author: "AUTHORNAME" title: "A series of posts, Volume 8" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } post9: addPost(id:9 author: "AUTHORNAME" title: "A series of posts, Volume 9" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title } }
  3. 選擇執行 (橘色播放按鈕)。

  4. 現在,讓我們來掃描資料表,一次會傳回五個結果。在查詢窗格中,新增下列查詢:

    query allPost { allPost(limit: 5) { posts { id title } nextToken } }
  5. 選擇執行 (橘色播放按鈕),然後選擇 allPost

    前五個帖子應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:

    { "data": { "allPost": { "posts": [ { "id": "5", "title": "A series of posts, Volume 5" }, { "id": "1", "title": "A series of posts, Volume 1" }, { "id": "6", "title": "A series of posts, Volume 6" }, { "id": "9", "title": "A series of posts, Volume 9" }, { "id": "7", "title": "A series of posts, Volume 7" } ], "nextToken": "<token>" } } }
  6. 您收到五個結果nextToken,以及可用來取得下一組結果的 。更新 allPost 查詢以包括來自之前結果組的 nextToken

    query allPost { allPost( limit: 5 nextToken: "<token>" ) { posts { id author } nextToken } }
  7. 選擇執行 (橘色播放按鈕),然後選擇 allPost

    其餘四個帖子應顯示在查詢窗格右側的結果窗格中。此結果集nextToken沒有 ,因為您已傳閱所有九個帖子,但沒有任何剩餘。其看起來與下列類似:

    { "data": { "allPost": { "posts": [ { "id": "2", "title": "A series of posts, Volume 2" }, { "id": "3", "title": "A series of posts, Volume 3" }, { "id": "4", "title": "A series of posts, Volume 4" }, { "id": "8", "title": "A series of posts, Volume 8" } ], "nextToken": null } } }

設定 allPostsBy作者解析程式 (Amazon DynamoDB Query)

除了掃描 Amazon DynamoDB 的所有文章之外,您也可以查詢 Amazon DynamoDB 來擷取特定作者建立的文章。您先前建立的 Amazon DynamoDB 資料表已有GlobalSecondaryIndex名為 的 author-index,您可以搭配 Amazon DynamoDB Query操作使用,以擷取特定作者建立的所有文章。

若要新增查詢

  1. 在 中API,選擇結構描述索引標籤。

  2. 修改 Schema (結構描述) 窗格中的 Query 類型以新增 allPostsByAuthor 查詢,如下所示:

    type Query { allPostsByAuthor(author: String!, limit: Int, nextToken: String): PaginatedPosts! allPost(limit: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }

    請注意,這使用與查詢相同的PaginatedPosts類型allPost

  3. 選擇 Save Schema (儲存結構描述)

  4. 在右側的解析程式窗格中,尋找Query類型上新建立allPostsByAuthor的欄位,然後選擇連接 。使用以下程式碼片段建立解析程式:

    import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const { limit = 20, nextToken, author } = ctx.arguments; return ddb.query({ index: 'author-index', query: { author: { eq: author } }, limit, nextToken, }); } export function response(ctx) { const { items: posts = [], nextToken } = ctx.result; return { posts, nextToken }; }

    allPost解析器一樣,此解析器有兩個選用引數:

    • limit - 指定在單一呼叫中傳回的項目數量上限。

    • nextToken - 擷取下一組結果 ( 的值nextToken可以從先前的呼叫取得)。

  5. 儲存對解析器所做的任何變更。

如需Query請求的詳細資訊,請參閱查詢參考文件。

呼叫 API,依作者查詢所有文章

現在,解析器已設定完成, AWS AppSync 知道如何針對author-index索引將傳入的allPostsByAuthor突變轉換為 DynamoDB Query操作。您現在可以查詢資料表以擷取特定作者的所有文章。

不過,在此之前,讓我們將更多文章填入資料表,因為到目前為止,每個文章都有相同的作者。

新增資料和查詢

  1. 在 中API,選擇查詢索引標籤。

  2. 查詢窗格中,新增下列突變:

    mutation addPost { post1: addPost(id:10 author: "Nadia" title: "The cutest dog in the world" content: "So cute. So very, very cute." url: "https://aws.amazon.com/appsync/" ) { author, title } post2: addPost(id:11 author: "Nadia" title: "Did you know...?" content: "AppSync works offline?" url: "https://aws.amazon.com/appsync/" ) { author, title } post3: addPost(id:12 author: "Steve" title: "I like GraphQL" content: "It's great" url: "https://aws.amazon.com/appsync/" ) { author, title } }
  3. 選擇執行 (橘色播放按鈕),然後選擇 addPost

  4. 現在,讓我們查詢資料表,傳回 Nadia 撰寫的所有文章。在查詢窗格中,新增下列查詢:

    query allPostsByAuthor { allPostsByAuthor(author: "Nadia") { posts { id title } nextToken } }
  5. 選擇執行 (橘色播放按鈕),然後選擇 allPostsByAuthor。撰寫的所有文章Nadia都應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "10", "title": "The cutest dog in the world" }, { "id": "11", "title": "Did you know...?" } ], "nextToken": null } } }
  6. 分頁適用於 Query,如同它適用於 Scan。例如,讓我們查詢 AUTHORNAME 的所有文章,一次取得五篇。

  7. 查詢窗格中,新增下列查詢:

    query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" limit: 5 ) { posts { id title } nextToken } }
  8. 選擇執行 (橘色播放按鈕),然後選擇 allPostsByAuthor。撰寫的所有文章AUTHORNAME都應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "6", "title": "A series of posts, Volume 6" }, { "id": "4", "title": "A series of posts, Volume 4" }, { "id": "2", "title": "A series of posts, Volume 2" }, { "id": "7", "title": "A series of posts, Volume 7" }, { "id": "1", "title": "A series of posts, Volume 1" } ], "nextToken": "<token>" } } }
  9. 使用之前查詢傳回的值更新 nextToken 引數,如下所示:

    query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" limit: 5 nextToken: "<token>" ) { posts { id title } nextToken } }
  10. 選擇執行 (橘色播放按鈕),然後選擇 allPostsByAuthor。撰寫的其餘文章AUTHORNAME應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "8", "title": "A series of posts, Volume 8" }, { "id": "5", "title": "A series of posts, Volume 5" }, { "id": "3", "title": "A series of posts, Volume 3" }, { "id": "9", "title": "A series of posts, Volume 9" } ], "nextToken": null } } }

使用 集

到目前為止,該Post類型一直是平面鍵/值物件。您也可以使用解析器建立複雜的物件模型,例如集合、清單和地圖。讓我們將 Post 類型更新為包含標籤。貼文可以有零個或多個標籤,這些標籤以字串集的形式存放在 DynamoDB 中。您也會設定一些變動來新增和移除標籤,以及新查詢以掃描含特定標籤的文章。

設定您的資料

  1. 在 中API,選擇結構描述索引標籤。

  2. 修改 Schema (結構描述) 窗格中的 Post 類型以新增 tags 欄位,如下所示:

    type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! tags: [String!] }
  3. 修改 Schema (結構描述) 窗格中的 Query 類型以新增 allPostsByTag 查詢,如下所示:

    type Query { allPostsByTag(tag: String!, limit: Int, nextToken: String): PaginatedPosts! allPostsByAuthor(author: String!, limit: Int, nextToken: String): PaginatedPosts! allPost(limit: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
  4. 修改 Schema (結構描述) 窗格中的 Mutation 類型以新增 addTagremoveTag 變動,如下所示:

    type Mutation { addTag(id: ID!, tag: String!): Post removeTag(id: ID!, tag: String!): Post deletePost(id: ID!, expectedVersion: Int): Post upvotePost(id: ID!): Post downvotePost(id: ID!): Post updatePost( id: ID!, author: String, title: String, content: String, url: String, expectedVersion: Int! ): Post addPost( author: String!, title: String!, content: String!, url: String! ): Post! }
  5. 選擇 Save Schema (儲存結構描述)

  6. 在右側的解析程式窗格中,尋找Query類型上新建立allPostsByTag的欄位,然後選擇連接 。使用以下程式碼片段建立您的解析程式:

    import * as ddb from '@aws-appsync/utils/dynamodb'; export function request(ctx) { const { limit = 20, nextToken, tag } = ctx.arguments; return ddb.scan({ limit, nextToken, filter: { tags: { contains: tag } } }); } export function response(ctx) { const { items: posts = [], nextToken } = ctx.result; return { posts, nextToken }; }
  7. 儲存您對解析器所做的任何變更。

  8. 現在,addTag使用下面的程式碼片段對 Mutation 欄位執行相同的操作:

    注意

    雖然 DynamoDB 公用程式目前不支援集操作,但您仍可以自行建立請求來與集互動。

    import { util } from '@aws-appsync/utils' export function request(ctx) { const { id, tag } = ctx.arguments const expressionValues = util.dynamodb.toMapValues({ ':plusOne': 1 }) expressionValues[':tags'] = util.dynamodb.toStringSet([tag]) return { operation: 'UpdateItem', key: util.dynamodb.toMapValues({ id }), update: { expression: `ADD tags :tags, version :plusOne`, expressionValues, }, } } export const response = (ctx) => ctx.result
  9. 儲存對解析器所做的任何變更。

  10. removeTag 使用下面的程式碼片段,再為 Mutation 欄位重複一次:

    import { util } from '@aws-appsync/utils'; export function request(ctx) { const { id, tag } = ctx.arguments; const expressionValues = util.dynamodb.toMapValues({ ':plusOne': 1 }); expressionValues[':tags'] = util.dynamodb.toStringSet([tag]); return { operation: 'UpdateItem', key: util.dynamodb.toMapValues({ id }), update: { expression: `DELETE tags :tags ADD version :plusOne`, expressionValues, }, }; } export const response = (ctx) => ctx.resultexport
  11. 儲存對解析器所做的任何變更。

呼叫 API 以使用標籤

現在您已設定解析程式, AWS AppSync 知道如何將傳入的 removeTagaddTagallPostsByTag請求轉換為 DynamoDB UpdateItemScan操作。為了嘗試看看,讓我們選擇您先前建立的其中一篇文章。例如,讓我們使用 Nadia 撰寫的一篇文章。

使用標籤

  1. 在 中API,選擇查詢索引標籤。

  2. 查詢窗格中,新增下列查詢:

    query allPostsByAuthor { allPostsByAuthor( author: "Nadia" ) { posts { id title } nextToken } }
  3. 選擇執行 (橘色播放按鈕),然後選擇 allPostsByAuthor

  4. Nadia 的所有文章都應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:

    { "data": { "allPostsByAuthor": { "posts": [ { "id": "10", "title": "The cutest dog in the world" }, { "id": "11", "title": "Did you known...?" } ], "nextToken": null } } }
  5. 讓我們使用名稱為世界最可愛的狗的 。記錄它,id因為稍後會用到它。現在,讓我們嘗試新增dog標籤。

  6. 查詢窗格中,新增下列突變。您也必須將 id 引數更新為您先前記下的值。

    mutation addTag { addTag(id:10 tag: "dog") { id title tags } }
  7. 選擇執行 (橘色播放按鈕),然後選擇 addTag。貼文會以新標籤更新:

    { "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }
  8. 您可以新增更多標籤。更新突變,將tag引數變更為 puppy

    mutation addTag { addTag(id:10 tag: "puppy") { id title tags } }
  9. 選擇執行 (橘色播放按鈕),然後選擇 addTag。貼文會以新標籤更新:

    { "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog", "puppy" ] } } }
  10. 您也可以刪除標籤。在查詢窗格中,新增下列突變。您還需要將id引數更新為您先前記下的值:

    mutation removeTag { removeTag(id:10 tag: "puppy") { id title tags } }
  11. 選擇執行 (橘色播放按鈕),然後選擇 removeTag。貼文將會更新,且 puppy 標籤將會刪除。

    { "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }
  12. 您也可以搜尋所有具有標籤的文章。在查詢窗格中,新增下列查詢:

    query allPostsByTag { allPostsByTag(tag: "dog") { posts { id title tags } nextToken } }
  13. 選擇執行 (橘色播放按鈕),然後選擇 allPostsByTag。具有 dog 標籤的所有文章將會傳回,如下所示:

    { "data": { "allPostsByTag": { "posts": [ { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog", "puppy" ] } ], "nextToken": null } } }

結論

在本教學課程中,您已建置 API,可讓您使用 AWS AppSync 和 GraphQL 在 DynamoDB 中操作Post物件。

若要清除,您可以從API主控台刪除 AWS AppSync GraphQL。

若要刪除與 DynamoDB 資料表相關聯的角色,請在資料來源資料表中選取資料來源,然後按一下編輯 。在建立或使用現有角色 下記下角色的值。前往IAM主控台以刪除角色。

若要刪除 DynamoDB 資料表,請按一下資料來源清單中的資料表名稱。這會將您帶到 DynamoDB 主控台,您可以在其中刪除資料表。