解析程式 - AWS AppSync GraphQL

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

解析程式

從前幾節中,您已了解結構描述和資料來源的元件。現在,我們需要解決結構描述和資料來源的互動方式。一切都從解析器開始。

解析器是程式碼單位,可處理當請求服務時,該欄位的資料將如何解決。解析程式會連接至您結構描述中類型內的特定欄位。它們最常用於為您的查詢、突變和訂閱欄位操作實作狀態變更操作。解析程式會處理用戶端的請求,然後傳回結果,結果可以是物件或純量等輸出類型的群組:

GraphQL schema with resolvers connecting to various AWS data sources for a single endpoint.

Resolver 執行時間

在 中 AWS AppSync,您必須先指定解析器的執行時間。解析器執行時間會指出執行解析器的環境。它還指定解析器將寫入的語言。 AWS AppSync 目前支援 APPSYNC_JS for JavaScript 和 Velocity 範本語言 (VTL)。請參閱JavaScript 適用於 的解析器和函數的執行期功能, JavaScript 或適用於 的解析器映射範本公用程式參考VTL。

解析器結構

以程式碼表示的解析程式可以用幾種方式建構。有單位管道解析程式。

單位解析程式

裝置解析器由程式碼組成,該程式碼定義單一請求和回應處理常式,這些請求和回應處理常式會針對資料來源執行。請求處理常式會將內容物件作為引數,並傳回用來呼叫資料來源的請求承載。回應處理常式會從資料來源接收承載,其中包含執行請求的結果。回應處理常式會將承載轉換為 GraphQL 回應,以解析 GraphQL 欄位。

GraphQL request flow showing request and response handlers interacting with a data source.

管道解析程式

實作管道解析程式時,會遵循一般結構:

  • 在步驟 之前:當用戶端提出請求時,所使用結構描述欄位的解析器 (通常是您的查詢、突變、訂閱) 會傳遞請求資料。解析器會開始在步驟處理常式之前使用 處理請求資料,這允許在資料移動到解析器之前執行一些預先處理操作。

  • Function(s):在步驟執行之前,請求會傳遞至函數清單。清單中的第一個函數會針對資料來源執行。函數是解析程式程式碼的子集,其中包含自己的請求和回應處理常式。請求移交器將取得請求資料,並根據資料來源執行操作。回應處理常式會先處理資料來源的回應,再將其傳回清單。如果有一個以上的函數,則請求資料會傳送至清單中要執行的下一個函數。清單中的函數會依開發人員定義的順序依序執行。執行所有函數後,最終結果會傳遞至後續步驟。

  • 步驟 :步驟後是處理常式函數,可讓您在最終函數的回應上執行一些最終操作,然後再將其傳遞至 GraphQL 回應。

GraphQL request flow diagram showing interactions between request, data sources, and response components.

Resolver 處理常式結構

處理常式是名為 Request和 的函數Response

export function request(ctx) { // Code goes here } export function response(ctx) { // Code goes here }

在單位解析程式中,只會有一組這些函數。在管道解析程式中,在步驟前後都會有一組 ,每個函數還會有一組額外的 。若要視覺化呈現效果,讓我們檢閱簡單的Query類型:

type Query { helloWorld: String! }

這是簡單的查詢,有一個欄位稱為helloWorld類型 String。假設我們一律希望此欄位傳回字串 "Hello World"。若要實作此行為,我們需要將解析器新增至此欄位。在單位解析程式中,我們可以新增如下內容:

export function request(ctx) { return {} } export function response(ctx) { return "Hello World" }

request 只能保留空白,因為我們沒有請求或處理資料。我們也可以假設資料來源為 None,表示此程式碼不需要執行任何調用。回應只會傳回「Hello World」。若要測試此解析程式,我們需要使用查詢類型提出請求:

query helloWorldTest { helloWorld }

這是名為 的查詢helloWorldTest,會傳回 helloWorld 欄位。執行時,helloWorld欄位解析器也會執行並傳回回應:

{ "data": { "helloWorld": "Hello World" } }

傳回像這樣的常數是最簡單的操作。實際上,您將傳回輸入、清單等。以下是更複雜的範例:

type Book { id: ID! title: String } type Query { getBooks: [Book] }

在這裡,我們會傳回 的清單Books。假設我們使用 DynamoDB 資料表來儲存書籍資料。我們的處理常式可能如下所示:

/** * Performs a scan on the dynamodb data source */ export function request(ctx) { return { operation: 'Scan' }; } /** * return a list of scanned post items */ export function response(ctx) { return ctx.result.items; }

我們的請求使用內建掃描操作來搜尋資料表中的所有項目、將調查結果存放在內容中,然後將其傳遞給回應。回應接受了結果項目,並在回應中傳回它們:

{ "data": { "getBooks": { "items": [ { "id": "abcdefgh-1234-1234-1234-abcdefghijkl", "title": "book1" }, { "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "title": "book2" }, ... ] } } }

Resolver 內容

在解析程式中,處理常式鏈中的每個步驟都必須知道先前步驟的資料狀態。一個處理常式的結果可以儲存並傳遞給另一個處理常式作為引數。GraphQL 定義四個基本解析器引數:

Resolver 基礎引數 描述
objrootparent 等等 父系的結果。
args 提供給 GraphQL 查詢中欄位的引數。
context 提供給每個解析器的值,並保留重要內容資訊,例如目前登入的使用者或資料庫的存取。
info 包含與目前查詢以及結構描述詳細資訊相關的欄位特定資訊的值。

在 中 AWS AppSync,context(ctx) 引數可以存放上述所有資料。這是根據請求建立的物件,包含授權憑證、結果資料、錯誤、請求中繼資料等資料。內容是程式設計人員操作來自請求其他部分的資料的簡單方法。再次擷取此程式碼片段:

/** * Performs a scan on the dynamodb data source */ export function request(ctx) { return { operation: 'Scan' }; } /** * return a list of scanned post items */ export function response(ctx) { return ctx.result.items; }

將請求的內容 (ctx) 作為引數;這是請求的狀態。它會執行資料表中所有項目的掃描,然後將結果儲存回 中的內容result。內容接著會傳遞至回應引數,該引數會存取 result並傳回其內容。

請求和剖析

當您對 GraphQL 服務進行查詢時,必須先執行剖析和驗證程序,才能執行。您的請求將被剖析並轉譯為抽象語法樹。樹狀目錄的內容是透過多個驗證演算法針對您的結構描述執行來驗證。在驗證步驟之後,會周遊和處理樹狀結構的節點。呼叫解析程式,結果會儲存在內容中,並傳回回應。例如,採取以下查詢:

query { Person { //object type name //scalar age //scalar } }

我們正在Person傳回 nameage 欄位。執行此查詢時,樹狀結構看起來會像這樣:

Hierarchical diagram showing query, Person, name, and age nodes connected by arrows.

從樹狀結構中,此請求似乎會在結構描述Query中搜尋 的根目錄。在查詢內, 欄位Person將得到解決。從先前的範例中,我們知道這可能是來自使用者的輸入,值清單等Person很可能與存放所需欄位 (nameage) 的物件類型相關聯。找到這兩個子欄位後,它們會依指定的順序 (name 後面接著 age) 解析。樹狀結構完全解決後,請求即完成,並將傳回用戶端。