View a markdown version of this page

Ekspresi kondisi - AWS AppSync GraphQL

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Ekspresi kondisi

Saat Anda mengubah objek di DynamoDB dengan menggunakan operasiPutItem,UpdateItem, dan DeleteItem DynamoDB, Anda dapat secara opsional menentukan ekspresi kondisi yang mengontrol apakah permintaan harus berhasil atau tidak, berdasarkan status objek yang sudah ada di DynamoDB sebelum operasi dilakukan.

Fungsi AWS AppSync DynamoDB memungkinkan ekspresi kondisi untuk ditentukan dalamPutItem,UpdateItem, dan objek DeleteItem permintaan, dan juga strategi untuk diikuti jika kondisi gagal dan objek tidak diperbarui.

Contoh 1

Objek PutItem permintaan berikut tidak memiliki ekspresi kondisi. Akibatnya, ia menempatkan item di DynamoDB bahkan jika item dengan kunci yang sama sudah ada, sehingga mengganti item yang ada.

import { util } from '@aws-appsync/utils'; export function request(ctx) { const { foo, bar, ...values} = ctx.args return { operation: 'PutItem', key: util.dynamodb.toMapValues({foo, bar}), attributeValues: util.dynamodb.toMapValues(values), }; }

Contoh 2

Ob PutItem jek berikut memang memiliki ekspresi kondisi yang memungkinkan operasi berhasil hanya jika item dengan kunci yang sama tidak ada di DynamoDB.

import { util } from '@aws-appsync/utils'; export function request(ctx) { const { foo, bar, ...values} = ctx.args return { operation: 'PutItem', key: util.dynamodb.toMapValues({foo, bar}), attributeValues: util.dynamodb.toMapValues(values), condition: { expression: "attribute_not_exists(id)" } }; }

Secara default, jika pemeriksaan kondisi gagal, fungsi AWS AppSync DynamoDB memberikan kesalahan untuk mutasi.

Namun, fungsi AWS AppSync DynamoDB menawarkan beberapa fitur tambahan untuk membantu pengembang menangani beberapa kasus tepi umum:

  • Jika fungsi AWS AppSync DynamoDB dapat menentukan bahwa nilai saat ini di DynamoDB cocok dengan hasil yang diinginkan, ia memperlakukan operasi seolah-olah tetap berhasil.

  • Alih-alih mengembalikan kesalahan, Anda dapat mengonfigurasi fungsi untuk memanggil fungsi Lambda khusus untuk memutuskan bagaimana fungsi AWS AppSync DynamoDB harus menangani kegagalan.

Ini dijelaskan secara lebih rinci di bagian Menangani kegagalan pemeriksaan kondisi.

Untuk informasi selengkapnya tentang ekspresi kondisi DynamoDB, lihat dokumentasi Dynam ConditionExpressions oDB.

Menentukan kondisi

Ob PutItem jekUpdateItem,, dan DeleteItem permintaan semuanya memungkinkan condition bagian opsional untuk ditentukan. Jika dihilangkan, tidak ada pemeriksaan kondisi yang dilakukan. Jika ditentukan, kondisi harus benar agar operasi berhasil.

Sebuah condition bagian memiliki struktur sebagai berikut:

type ConditionCheckExpression = { expression: string; expressionNames?: { [key: string]: string}; expressionValues?: { [key: string]: any}; equalsIgnore?: string[]; consistentRead?: boolean; conditionalCheckFailedHandler?: { strategy: 'Custom' | 'Reject'; lambdaArn?: string; }; };

Bidang berikut menentukan kondisi:

expression

Ekspresi pembaruan itu sendiri. Untuk informasi selengkapnya tentang cara menulis ekspresi kondisi, lihat dokumentasi DynamoDB ConditionExpressions . Bidang ini harus ditentukan.

expressionNames

Substitusi untuk placeholder nama atribut ekspresi, dalam bentuk pasangan kunci-nilai. Kunci sesuai dengan placeholder nama yang digunakan dalam ekspresi, dan nilainya harus berupa string yang sesuai dengan nama atribut item di DynamoDB. Bidang ini opsional, dan hanya boleh diisi dengan substitusi untuk placeholder nama atribut ekspresi yang digunakan dalam ekspresi.

expressionValues

Substitusi untuk placeholder nilai atribut ekspresi, dalam bentuk pasangan kunci-nilai. Kunci sesuai dengan placeholder nilai yang digunakan dalam ekspresi, dan nilainya harus berupa nilai yang diketik. Untuk informasi selengkapnya tentang cara menentukan “nilai yang diketik”, lihat Sistem tipe (pemetaan permintaan). Ini harus ditentukan. Bidang ini opsional, dan hanya boleh diisi dengan substitusi untuk placeholder nilai atribut ekspresi yang digunakan dalam ekspresi.

Bidang yang tersisa memberi tahu fungsi AWS AppSync DynamoDB cara menangani kegagalan pemeriksaan kondisi:

equalsIgnore

Ketika pemeriksaan kondisi gagal saat menggunakan PutItem operasi, fungsi AWS AppSync DynamoDB membandingkan item yang saat ini ada di DynamoDB dengan item yang coba ditulisnya. Jika mereka sama, itu memperlakukan operasi seolah-olah berhasil. Anda dapat menggunakan equalsIgnore bidang untuk menentukan daftar atribut yang AWS AppSync harus diabaikan saat melakukan perbandingan itu. Misalnya, jika satu-satunya perbedaan adalah version atribut, ia memperlakukan operasi seolah-olah berhasil. Ini adalah bidang opsional.

consistentRead

Ketika pemeriksaan kondisi gagal, AWS AppSync mendapatkan nilai item saat ini dari DynamoDB menggunakan pembacaan yang sangat konsisten. Anda dapat menggunakan bidang ini untuk memberi tahu fungsi AWS AppSync DynamoDB untuk menggunakan pembacaan yang akhirnya konsisten sebagai gantinya. Bidang ini opsional, dan default ketrue.

conditionalCheckFailedHandler

Bagian ini memungkinkan Anda untuk menentukan bagaimana fungsi AWS AppSync DynamoDB memperlakukan kegagalan pemeriksaan kondisi setelah membandingkan nilai saat ini di DynamoDB dengan hasil yang diharapkan. Bagian ini opsional. Jika dihilangkan, itu default ke strategi. Reject

strategy

Strategi yang diambil fungsi AWS AppSync DynamoDB setelah membandingkan nilai saat ini di DynamoDB dengan hasil yang diharapkan. Bidang ini wajib diisi dan memiliki kemungkinan nilai berikut:

Reject

Mutasi gagal, dan kesalahan ditambahkan ke respons GraphQL.

Custom

Fungsi AWS AppSync DynamoDB memanggil fungsi Lambda khusus untuk memutuskan bagaimana menangani kegagalan pemeriksaan kondisi. Ketika strategy disetel keCustom, lambdaArn bidang harus berisi ARN dari fungsi Lambda untuk dipanggil.

lambdaArn

ARN dari fungsi Lambda untuk dipanggil yang menentukan bagaimana fungsi AWS AppSync DynamoDB harus menangani kegagalan pemeriksaan kondisi. Bidang ini hanya boleh ditentukan saat strategy disetel keCustom. Untuk informasi selengkapnya tentang cara menggunakan fitur ini, lihat Menangani kegagalan pemeriksaan kondisi.

Menangani kegagalan pemeriksaan kondisi

Ketika pemeriksaan kondisi gagal, fungsi AWS AppSync DynamoDB dapat meneruskan kesalahan untuk mutasi dan nilai objek saat ini dengan menggunakan utilitasutil.appendError. Namun, fungsi AWS AppSync DynamoDB menawarkan beberapa fitur tambahan untuk membantu pengembang menangani beberapa kasus tepi umum:

  • Jika fungsi AWS AppSync DynamoDB dapat menentukan bahwa nilai saat ini di DynamoDB cocok dengan hasil yang diinginkan, ia memperlakukan operasi seolah-olah tetap berhasil.

  • Alih-alih mengembalikan kesalahan, Anda dapat mengonfigurasi fungsi untuk memanggil fungsi Lambda khusus untuk memutuskan bagaimana fungsi AWS AppSync DynamoDB harus menangani kegagalan.

Diagram alur untuk proses ini adalah:

Diagram alur yang menunjukkan proses upaya mutasi dengan poin keputusan untuk kesuksesan, strategi, dan tindakan.

Memeriksa hasil yang diinginkan

Ketika pemeriksaan kondisi gagal, fungsi AWS AppSync DynamoDB melakukan permintaan GetItem DynamoDB untuk mendapatkan nilai item saat ini dari DynamoDB. Secara default, ini menggunakan pembacaan yang sangat konsisten, namun ini dapat dikonfigurasi menggunakan consistentRead bidang di condition blok dan membandingkannya dengan hasil yang diharapkan:

  • Untuk PutItem operasi, fungsi AWS AppSync DynamoDB membandingkan nilai saat ini dengan nilai yang dicoba untuk ditulisnya, tidak termasuk atribut apa pun yang tercantum dalam per equalsIgnore bandingan. Jika itemnya sama, itu memperlakukan operasi sebagai berhasil dan mengembalikan item yang diambil dari DynamoDB. Jika tidak, itu mengikuti strategi yang dikonfigurasi.

    Misalnya, jika objek PutItem permintaan terlihat seperti berikut:

    import { util } from '@aws-appsync/utils'; export function request(ctx) { const { id, name, version} = ctx.args return { operation: 'PutItem', key: util.dynamodb.toMapValues({foo, bar}), attributeValues: util.dynamodb.toMapValues({ name, version: version+1 }), condition: { expression: "version = :expectedVersion", expressionValues: util.dynamodb.toMapValues({':expectedVersion': version}), equalsIgnore: ['version'] } }; }

    Dan item yang saat ini ada di DynamoDB terlihat seperti berikut:

    { "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }

    Fungsi AWS AppSync DynamoDB akan membandingkan item yang coba ditulisnya dengan nilai saat ini, melihat bahwa satu-satunya perbedaan adalah version bidang, tetapi karena dikonfigurasi untuk mengabaikan version bidang, ia memperlakukan operasi sebagai berhasil dan mengembalikan item yang diambil dari DynamoDB.

  • Untuk DeleteItem operasi, fungsi AWS AppSync DynamoDB memeriksa untuk memverifikasi bahwa item dikembalikan dari DynamoDB. Jika tidak ada item yang dikembalikan, itu memperlakukan operasi sebagai berhasil. Jika tidak, itu mengikuti strategi yang dikonfigurasi.

  • Untuk UpdateItem operasi, fungsi AWS AppSync DynamoDB tidak memiliki informasi yang cukup untuk menentukan apakah item saat ini di DynamoDB cocok dengan hasil yang diharapkan, dan oleh karena itu mengikuti strategi yang dikonfigurasi.

Jika status objek saat ini di DynamoDB berbeda dari hasil yang diharapkan, fungsi AWS AppSync DynamoDB mengikuti strategi yang dikonfigurasi, untuk menolak mutasi atau memanggil fungsi Lambda untuk menentukan apa yang harus dilakukan selanjutnya.

Mengikuti strategi “tolak”

Saat mengikuti Reject strategi, fungsi AWS AppSync DynamoDB mengembalikan kesalahan untuk mutasi.

Misalnya, diberikan permintaan mutasi berikut:

mutation { updatePerson(id: 1, name: "Steve", expectedVersion: 1) { Name theVersion } }

Jika item yang dikembalikan dari DynamoDB terlihat seperti berikut:

{ "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }

Dan pengendali respons fungsi terlihat seperti berikut:

import { util } from '@aws-appsync/utils'; export function response(ctx) { const { version, ...values } = ctx.result; const result = { ...values, theVersion: version }; if (ctx.error) { if (error) { return util.appendError(error.message, error.type, result, null); } } return result }

Respons GraphQL terlihat seperti berikut:

{ "data": null, "errors": [ { "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)" "errorType": "DynamoDB:ConditionalCheckFailedException", ... } ] }

Juga, jika ada bidang dalam objek yang dikembalikan diisi oleh resolver lain dan mutasi telah berhasil, mereka tidak akan diselesaikan ketika objek dikembalikan di error bagian tersebut.

Mengikuti strategi “kustom”

Saat mengikuti Custom strategi, fungsi AWS AppSync DynamoDB memanggil fungsi Lambda untuk memutuskan apa yang harus dilakukan selanjutnya. Fungsi Lambda memilih salah satu opsi berikut:

  • rejectmutasi. Ini memberi tahu fungsi AWS AppSync DynamoDB untuk berperilaku seolah-olah strategi yang dikonfigurasiReject, mengembalikan kesalahan untuk mutasi dan nilai objek saat ini di DynamoDB seperti yang dijelaskan di bagian sebelumnya.

  • discardmutasi. Ini memberitahu fungsi AWS AppSync DynamoDB untuk diam-diam mengabaikan kegagalan pemeriksaan kondisi dan mengembalikan nilai di DynamoDB.

  • retrymutasi. Ini memberi tahu fungsi AWS AppSync DynamoDB untuk mencoba kembali mutasi dengan objek permintaan baru.

Permintaan pemanggilan Lambda

Fungsi AWS AppSync DynamoDB memanggil fungsi Lambda yang ditentukan dalam. lambdaArn Ini menggunakan service-role-arn konfigurasi yang sama pada sumber data. Muatan pemanggilan memiliki struktur sebagai berikut:

{ "arguments": { ... }, "requestMapping": {... }, "currentValue": { ... }, "resolver": { ... }, "identity": { ... } }

Bidang didefinisikan sebagai berikut:

arguments

Argumen dari mutasi GraphQL. Ini sama dengan argumen yang tersedia untuk objek permintaan dicontext.arguments.

requestMapping

Objek permintaan untuk operasi ini.

currentValue

Nilai objek saat ini di DynamoDB.

resolver

Informasi tentang AWS AppSync resolver atau fungsi.

identity

Informasi tentang penelepon. Ini sama dengan informasi identitas yang tersedia untuk objek permintaan dicontext.identity.

Contoh lengkap dari payload:

{ "arguments": { "id": "1", "name": "Steve", "expectedVersion": 1 }, "requestMapping": { "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : { "S" : "1" } }, "attributeValues" : { "name" : { "S" : "Steve" }, "version" : { "N" : 2 } }, "condition" : { "expression" : "version = :expectedVersion", "expressionValues" : { ":expectedVersion" : { "N" : 1 } }, "equalsIgnore": [ "version" ] } }, "currentValue": { "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }, "resolver": { "tableName": "People", "awsRegion": "us-west-2", "parentType": "Mutation", "field": "updatePerson", "outputType": "Person" }, "identity": { "accountId": "123456789012", "sourceIp": "x.x.x.x", "user": "AIDAAAAAAAAAAAAAAAAAA", "userArn": "arn:aws:iam::123456789012:user/appsync" } }

Respons Pemanggilan Lambda

Fungsi Lambda dapat memeriksa payload pemanggilan dan menerapkan logika bisnis apa pun untuk memutuskan bagaimana fungsi AWS AppSync DynamoDB harus menangani kegagalan. Ada tiga opsi untuk menangani kegagalan pemeriksaan kondisi:

  • rejectmutasi. Muatan respons untuk opsi ini harus memiliki struktur ini:

    { "action": "reject" }

    Ini memberi tahu fungsi AWS AppSync DynamoDB untuk berperilaku seolah-olah strategi yang dikonfigurasiReject, mengembalikan kesalahan untuk mutasi dan nilai objek saat ini di DynamoDB, seperti yang dijelaskan pada bagian di atas.

  • discardmutasi. Muatan respons untuk opsi ini harus memiliki struktur ini:

    { "action": "discard" }

    Ini memberitahu fungsi AWS AppSync DynamoDB untuk diam-diam mengabaikan kegagalan pemeriksaan kondisi dan mengembalikan nilai di DynamoDB.

  • retrymutasi. Muatan respons untuk opsi ini harus memiliki struktur ini:

    { "action": "retry", "retryMapping": { ... } }

    Ini memberi tahu fungsi AWS AppSync DynamoDB untuk mencoba kembali mutasi dengan objek permintaan baru. Struktur retryMapping bagian tergantung pada operasi DynamoDB, dan merupakan bagian dari objek permintaan penuh untuk operasi itu.

    UntukPutItem, retryMapping bagian ini memiliki struktur sebagai berikut. Untuk deskripsi attributeValues bidang, lihat PutItem.

    { "attributeValues": { ... }, "condition": { "equalsIgnore" = [ ... ], "consistentRead" = true } }

    UntukUpdateItem, retryMapping bagian ini memiliki struktur sebagai berikut. Untuk deskripsi update bagian, lihat UpdateItem.

    { "update" : { "expression" : "someExpression" "expressionNames" : { "#foo" : "foo" }, "expressionValues" : { ":bar" : ... typed value } }, "condition": { "consistentRead" = true } }

    UntukDeleteItem, retryMapping bagian ini memiliki struktur sebagai berikut.

    { "condition": { "consistentRead" = true } }

    Tidak ada cara untuk menentukan operasi atau kunci yang berbeda untuk dikerjakan. Fungsi AWS AppSync DynamoDB hanya memungkinkan percobaan ulang operasi yang sama pada objek yang sama. Juga, condition bagian ini tidak mengizinkan a conditionalCheckFailedHandler untuk ditentukan. Jika percobaan ulang gagal, fungsi AWS AppSync DynamoDB mengikuti strategi. Reject

Berikut adalah contoh fungsi Lambda untuk menangani PutItem permintaan yang gagal. Logika bisnis melihat siapa yang melakukan panggilan. Jika dibuat olehjeffTheAdmin, ia mencoba lagi permintaan, memperbarui version dan expectedVersion dari item yang saat ini ada di DynamoDB. Jika tidak, ia menolak mutasi.

exports.handler = (event, context, callback) => { console.log("Event: "+ JSON.stringify(event)); // Business logic goes here. var response; if ( event.identity.user == "jeffTheAdmin" ) { response = { "action" : "retry", "retryMapping" : { "attributeValues" : event.requestMapping.attributeValues, "condition" : { "expression" : event.requestMapping.condition.expression, "expressionValues" : event.requestMapping.condition.expressionValues } } } response.retryMapping.attributeValues.version = { "N" : event.currentValue.version.N + 1 } response.retryMapping.condition.expressionValues[':expectedVersion'] = event.currentValue.version } else { response = { "action" : "reject" } } console.log("Response: "+ JSON.stringify(response)) callback(null, response) };