本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 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
-
開啟 AppSync 主控台,然後選擇建立 API。
-
從頭選取設計,然後選擇下一步。
-
為您的 API 命名
PostTutorialAPI
,然後選擇下一個 。跳至檢閱頁面,同時將其餘選項設定為其預設值,然後選擇Create
。
AWS AppSync 主控台API會為您建立新的 GraphQL。透過停用,它會使用API金鑰身分驗證模式。您可以使用 主控台來設定 GraphQL 的其餘部分,API並在本教學課程的其餘部分針對它執行查詢。
定義基本文章 API
現在您已擁有 GraphQL API,您可以設定基本結構描述,以允許基本建立、擷取和刪除貼文資料。
將資料新增至您的結構描述
-
在 中API,選擇結構描述索引標籤。
-
我們將建立結構描述,以定義
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! }
-
選擇 Save Schema (儲存結構描述)。
設定 Amazon DynamoDB 資料表
AWS AppSync 主控台可協助佈建所需的 AWS 資源,以將您自己的資源存放在 Amazon DynamoDB 資料表中。在此步驟中,您將建立 Amazon DynamoDB 資料表來儲存您的文章。您也會設定次要索引,稍後再使用。
若要建立 Amazon DynamoDB 資料表
-
在結構描述頁面上,選擇建立資源 。
-
選擇使用現有類型 ,然後選擇
Post
類型。 -
在其他索引區段中,選擇新增索引 。
-
為索引命名
author-index
。 -
將
Primary key
設定為author
,將Sort
金鑰設定為None
。 -
停用自動產生 GraphQL 。在此範例中,我們將自行建立解析程式。
-
選擇 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
類型不同,此功能會很有用,但如果他們的形狀一樣,您只需傳遞資料。
設定解析器
-
在 中API,選擇結構描述索引標籤。
-
在解析程式窗格中,尋找
Mutation
類型下方的addPost
欄位,然後選擇連接 。 -
選擇您的資料來源,然後選擇建立 。
-
在程式碼編輯器中,使用此程式碼片段取代程式碼:
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 }
-
選擇 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
操作。您現在可以執行變動以將項目放置到資料表中。
執行操作
-
在 中API,選擇查詢索引標籤。
-
在查詢窗格中,新增下列突變:
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 } }
-
選擇執行 (橘色播放按鈕),然後選擇
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 } } }
下列說明顯示發生的情況:
-
AWS AppSync 收到
addPost
突變請求。 -
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/' } } }
-
AWS AppSync 使用此值來產生和執行 Amazon DynamoDB
PutItem
請求。 -
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 }
-
回應處理常式會立即傳回結果 (
return ctx.result
)。 -
最終結果會顯示在 GraphQL 回應中。
設定 getPost 解析程式 (Amazon DynamoDB GetItem)
現在您可以將資料新增至 Amazon DynamoDB 資料表,您需要設定getPost
查詢,以便從資料表擷取該資料。若要執行此作業,您可以設定另一個解析程式。
若要新增您的解析器
-
在 中API,選擇結構描述索引標籤。
-
在右側解析程式窗格中,尋找
Query
類型上的getPost
欄位,然後選擇連接 。 -
選擇您的資料來源,然後選擇建立 。
-
在程式碼編輯器中,使用此程式碼片段取代程式碼:
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
-
儲存您的解析程式。
注意
在此解析程式中,我們使用回應處理常式的箭頭函數表達式。
呼叫 API以取得文章
現在已設定解析器, AWS AppSync 知道如何將傳入的getPost
查詢轉換為 Amazon DynamoDB GetItem
操作。您現在可以執行查詢,擷取您稍早建立的貼文。
執行查詢
-
在 中API,選擇查詢索引標籤。
-
在查詢窗格中,新增下列程式碼,並使用您在建立文章後複製的 ID:
query getPost { getPost(id: "123") { id author title content url ups downs version } }
-
選擇執行 (橘色播放按鈕),然後選擇
getPost
。新建立的文章結果應出現在查詢窗格右側的結果窗格中。 -
從 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
查詢只需要 id
、 author
和 title
,您可以變更請求函數以使用投影表達式,以僅指定您想要從 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
更新解析器
-
在 中API,選擇結構描述索引標籤。
-
修改 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! }
-
選擇 Save Schema (儲存結構描述)。
-
在右側的解析程式窗格中,尋找
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;
-
儲存您所做的任何變更。
此解析器會使用 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
物件。
更新物件
-
在 中API,選擇查詢索引標籤。
-
在查詢窗格中,新增下列突變。您還需要將
id
引數更新為您先前記下的值:mutation updatePost { updatePost( id:123 title: "An empty story" content: null expectedVersion: 1 ) { id author title content url ups downs version } }
-
選擇執行 (橘色播放按鈕),然後選擇
updatePost
。 -
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 僅更新 title
和 content
欄位。所有其他欄位都是單獨保留的 (除了增加version
欄位)。您可以將 title
屬性設定為新值,並從文章中移除 content
屬性。author
、url
、ups
和 downs
欄位維持原狀。嘗試再次執行突變請求,同時保持請求的原樣。您應該會看到類似以下的回應:
{ "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
:
-
第一次執行請求時,Amazon DynamoDB 中文章
version
的欄位值為1
,符合引expectedVersion
數。請求成功,這表示version
欄位已在 Amazon DynamoDB 中遞增至2
。 -
第二次執行請求時,Amazon DynamoDB 中文章
version
的欄位值為2
,這與expectedVersion
引數不相符。
此模式通常稱為樂觀鎖定。
建立投票突變 (Amazon DynamoDB UpdateItem)
Post
類型包含 ups
和 downs
欄位,以啟用向上和向下記錄。不過,目前 API不會讓我們對它們進行任何動作。讓我們新增突變,讓我們向上和向下移動文章。
新增您的突變
-
在 中API,選擇結構描述索引標籤。
-
在結構描述窗格中,修改
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 }
-
選擇 Save Schema (儲存結構描述)。
-
在右側的解析程式窗格中,尋找
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;
-
儲存您所做的任何變更。
呼叫 API以向上或向下移動文章
現在已設定新的解析程式, AWS AppSync 知道如何將傳入upvotePost
或downvote
突變轉譯為 Amazon DynamoDB UpdateItem
操作。您現在可以執行變動,對您之前建立的文章表達贊同或不贊同。
執行您的突變
-
在 中API,選擇查詢索引標籤。
-
在查詢窗格中,新增下列突變。您還需要將
id
引數更新為您先前記下的值:mutation votePost { vote(id:123, direction: UP) { id author title content url ups downs version } }
-
選擇執行 (橘色播放按鈕),然後選擇
votePost
。 -
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 } } }
-
選擇再執行幾次。每次執行查詢
1
時,您應該會看到ups
和version
欄位遞增。 -
變更查詢以使用不同的 呼叫它
DIRECTION
。mutation votePost { vote(id:123, direction: DOWN) { id author title content url ups downs version } }
-
選擇執行 (橘色播放按鈕),然後選擇
votePost
。這次,您應該會看到
1
downs
和version
欄位在每次執行查詢時遞增。
設定 deletePost 解析程式 (Amazon DynamoDB DeleteItem)
接下來,您會想要建立突變來刪除文章。您將使用 Amazon DynamoDB DeleteItem
操作來執行此操作。
新增您的突變
-
在結構描述中,選擇結構描述索引標籤。
-
在結構描述窗格中,修改
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! }
-
這次,您將
expectedVersion
欄位設為選用。接下來,選擇儲存結構描述 。 -
在右側的解析程式窗格中,尋找
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
操作。您現在可以執行變動以在資料表中刪除項目。
執行您的突變
-
在 中API,選擇查詢索引標籤。
-
在查詢窗格中,新增下列突變。您還需要將
id
引數更新為您先前記下的值:mutation deletePost { deletePost(id:123) { id author title content url ups downs version } }
-
選擇執行 (橘色播放按鈕),然後選擇
deletePost
。 -
文章會從 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 } } }
-
只有在此呼叫
deletePost
是實際從 Amazon DynamoDB 刪除的值時,才會傳回該值。再次選擇執行。 -
呼叫仍然成功,但不會傳回任何值:
{ "data": { "deletePost": null } }
-
現在,讓我們嘗試刪除文章,但這次會指定
expectedValue
。首先,您需要建立新的文章,因為您剛刪除了目前為止使用過的文章。 -
在查詢窗格中,新增下列突變:
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 } }
-
選擇執行 (橘色播放按鈕),然後選擇
addPost
。 -
新建立的文章結果應出現在查詢窗格右側的結果窗格中。記錄新建立物件
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 } } }
-
現在,讓我們嘗試刪除具有 非法值的文章expectedVersion。在查詢窗格中,新增下列突變。您還需要將
id
引數更新為您先前記下的值:mutation deletePost { deletePost( id:123 expectedVersion: 9999 ) { id author title content url ups downs version } }
-
選擇執行 (橘色播放按鈕),然後選擇
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)" } ] }
-
請求失敗,因為條件表達式評估為
false
。Amazon DynamoDB 中version
帖子的值與引數中expectedValue
指定的值不相符。會在 GraphQL 回應data
區段中errors
欄位傳回物件的目前值。重試要求,但更正expectedVersion
:mutation deletePost { deletePost( id:123 expectedVersion: 1 ) { id author title content url ups downs version } }
-
選擇執行 (橘色播放按鈕),然後選擇
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 } } }
-
再次選擇執行。呼叫仍然成功,但這次不會傳回任何值,因為文章已在 Amazon DynamoDB 中刪除。
{ "data": { "deletePost": null } }
設定 allPost 解析程式 (Amazon DynamoDB Scan)
目前為止,只有在您知道要查看的每個文章id
的 API 時才有用。讓我們新增新的解析程式,傳回資料表中的所有文章。
新增您的突變
-
在 中API,選擇結構描述索引標籤。
-
修改 Schema (結構描述) 窗格中的
Query
類型以新增allPost
查詢,如下所示:type Query { allPost(limit: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
-
新增
PaginationPosts
類型:type PaginatedPosts { posts: [Post!]! nextToken: String }
-
選擇 Save Schema (儲存結構描述)。
-
在右側的解析程式窗格中,尋找
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
來自稍後的位置)。
-
-
儲存對解析器所做的任何變更。
如需Scan
請求的詳細資訊,請參閱掃描參考文件。
呼叫 API以掃描所有文章
現在已設定解析器, AWS AppSync 知道如何將傳入的allPost
查詢轉換為 Amazon DynamoDB Scan
操作。您現在可以掃描資料表來擷取所有文章。在您可以嘗試之前,您必須將一些資料填入資料表,因為您已刪除目前為止所使用的項目。
新增和查詢資料
-
在 中API,選擇查詢索引標籤。
-
在查詢窗格中,新增下列突變:
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 } }
-
選擇執行 (橘色播放按鈕)。
-
現在,讓我們來掃描資料表,一次會傳回五個結果。在查詢窗格中,新增下列查詢:
query allPost { allPost(limit: 5) { posts { id title } nextToken } }
-
選擇執行 (橘色播放按鈕),然後選擇
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>" } } }
-
您收到五個結果
nextToken
,以及可用來取得下一組結果的 。更新allPost
查詢以包括來自之前結果組的nextToken
:query allPost { allPost( limit: 5 nextToken: "<token>" ) { posts { id author } nextToken } }
-
選擇執行 (橘色播放按鈕),然後選擇
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
操作使用,以擷取特定作者建立的所有文章。
若要新增查詢
-
在 中API,選擇結構描述索引標籤。
-
修改 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
。 -
選擇 Save Schema (儲存結構描述)。
-
在右側的解析程式窗格中,尋找
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
可以從先前的呼叫取得)。
-
-
儲存對解析器所做的任何變更。
如需Query
請求的詳細資訊,請參閱查詢參考文件。
呼叫 API,依作者查詢所有文章
現在,解析器已設定完成, AWS AppSync 知道如何針對author-index
索引將傳入的allPostsByAuthor
突變轉換為 DynamoDB Query
操作。您現在可以查詢資料表以擷取特定作者的所有文章。
不過,在此之前,讓我們將更多文章填入資料表,因為到目前為止,每個文章都有相同的作者。
新增資料和查詢
-
在 中API,選擇查詢索引標籤。
-
在查詢窗格中,新增下列突變:
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 } }
-
選擇執行 (橘色播放按鈕),然後選擇
addPost
。 -
現在,讓我們查詢資料表,傳回
Nadia
撰寫的所有文章。在查詢窗格中,新增下列查詢:query allPostsByAuthor { allPostsByAuthor(author: "Nadia") { posts { id title } nextToken } }
-
選擇執行 (橘色播放按鈕),然後選擇
allPostsByAuthor
。撰寫的所有文章Nadia
都應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:{ "data": { "allPostsByAuthor": { "posts": [ { "id": "10", "title": "The cutest dog in the world" }, { "id": "11", "title": "Did you know...?" } ], "nextToken": null } } }
-
分頁適用於
Query
,如同它適用於Scan
。例如,讓我們查詢AUTHORNAME
的所有文章,一次取得五篇。 -
在查詢窗格中,新增下列查詢:
query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" limit: 5 ) { posts { id title } nextToken } }
-
選擇執行 (橘色播放按鈕),然後選擇
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>" } } }
-
使用之前查詢傳回的值更新
nextToken
引數,如下所示:query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" limit: 5 nextToken: "<token>" ) { posts { id title } nextToken } }
-
選擇執行 (橘色播放按鈕),然後選擇
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 中。您也會設定一些變動來新增和移除標籤,以及新查詢以掃描含特定標籤的文章。
設定您的資料
-
在 中API,選擇結構描述索引標籤。
-
修改 Schema (結構描述) 窗格中的
Post
類型以新增tags
欄位,如下所示:type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! tags: [String!] }
-
修改 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 }
-
修改 Schema (結構描述) 窗格中的
Mutation
類型以新增addTag
和removeTag
變動,如下所示: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! }
-
選擇 Save Schema (儲存結構描述)。
-
在右側的解析程式窗格中,尋找
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 }; }
-
儲存您對解析器所做的任何變更。
-
現在,
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
-
儲存對解析器所做的任何變更。
-
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
-
儲存對解析器所做的任何變更。
呼叫 API 以使用標籤
現在您已設定解析程式, AWS AppSync 知道如何將傳入的 removeTag
、 addTag
和 allPostsByTag
請求轉換為 DynamoDB UpdateItem
和 Scan
操作。為了嘗試看看,讓我們選擇您先前建立的其中一篇文章。例如,讓我們使用 Nadia
撰寫的一篇文章。
使用標籤
-
在 中API,選擇查詢索引標籤。
-
在查詢窗格中,新增下列查詢:
query allPostsByAuthor { allPostsByAuthor( author: "Nadia" ) { posts { id title } nextToken } }
-
選擇執行 (橘色播放按鈕),然後選擇
allPostsByAuthor
。 -
Nadia 的所有文章都應出現在查詢窗格右側的結果窗格中。其看起來與下列類似:
{ "data": { "allPostsByAuthor": { "posts": [ { "id": "10", "title": "The cutest dog in the world" }, { "id": "11", "title": "Did you known...?" } ], "nextToken": null } } }
-
讓我們使用名稱為世界最可愛的狗的 。記錄它,
id
因為稍後會用到它。現在,讓我們嘗試新增dog
標籤。 -
在查詢窗格中,新增下列突變。您也必須將
id
引數更新為您先前記下的值。mutation addTag { addTag(id:10 tag: "dog") { id title tags } }
-
選擇執行 (橘色播放按鈕),然後選擇
addTag
。貼文會以新標籤更新:{ "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }
-
您可以新增更多標籤。更新突變,將
tag
引數變更為puppy
:mutation addTag { addTag(id:10 tag: "puppy") { id title tags } }
-
選擇執行 (橘色播放按鈕),然後選擇
addTag
。貼文會以新標籤更新:{ "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog", "puppy" ] } } }
-
您也可以刪除標籤。在查詢窗格中,新增下列突變。您還需要將
id
引數更新為您先前記下的值:mutation removeTag { removeTag(id:10 tag: "puppy") { id title tags } }
-
選擇執行 (橘色播放按鈕),然後選擇
removeTag
。貼文將會更新,且puppy
標籤將會刪除。{ "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }
-
您也可以搜尋所有具有標籤的文章。在查詢窗格中,新增下列查詢:
query allPostsByTag { allPostsByTag(tag: "dog") { posts { id title tags } nextToken } }
-
選擇執行 (橘色播放按鈕),然後選擇
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 主控台,您可以在其中刪除資料表。