Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Penyelesai
Dari bagian sebelumnya, Anda belajar tentang komponen skema dan sumber data. Sekarang, kita perlu membahas bagaimana skema dan sumber data berinteraksi. Semuanya dimulai dengan resolver.
Resolver adalah unit kode yang menangani bagaimana data bidang itu akan diselesaikan ketika permintaan dibuat ke layanan. Resolver dilampirkan ke bidang tertentu dalam tipe Anda dalam skema Anda. Mereka paling sering digunakan untuk mengimplementasikan operasi pengubah status untuk operasi bidang kueri, mutasi, dan langganan Anda. Resolver akan memproses permintaan klien, kemudian mengembalikan hasilnya, yang dapat berupa sekelompok jenis output seperti objek atau skalar:
Waktu proses penyelesai
Di AWS AppSync, Anda harus terlebih dahulu menentukan runtime untuk resolver Anda. Runtime resolver menunjukkan lingkungan di mana resolver dijalankan. Ini juga menentukan bahasa yang akan digunakan resolver Anda untuk ditulis. AWS AppSync saat ini mendukung APPSYNC_JS untuk JavaScript dan Velocity Template Language (VTL). Lihat fitur JavaScript runtime untuk resolver dan fungsi untuk JavaScript atau referensi utilitas template pemetaan Resolver untuk VTL.
Struktur resolver
Code-wise, resolver dapat disusun dalam beberapa cara. Ada penyel esai unit dan pipa.
Penyelesai unit
Unit resolver terdiri dari kode yang mendefinisikan permintaan tunggal dan penanganan respons yang dieksekusi terhadap sumber data. Penangan permintaan mengambil objek konteks sebagai argumen dan mengembalikan payload permintaan yang digunakan untuk memanggil sumber data Anda. Respon handler menerima payload kembali dari sumber data dengan hasil permintaan yang dieksekusi. Penangan respons mengubah payload menjadi respons GraphQL untuk menyelesaikan bidang GraphQL.
Penyelesai pipa
Saat menerapkan penyelesai pipa, ada struktur umum yang mereka ikuti:
-
Sebelum langkah: Ketika permintaan dibuat oleh klien, resolver untuk bidang skema yang digunakan (biasanya kueri, mutasi, langganan Anda) diteruskan data permintaan. Resolver akan mulai memproses data permintaan dengan handler langkah sebelum, yang memungkinkan beberapa operasi pra-pemrosesan dilakukan sebelum data bergerak melalui resolver.
-
Fungsi: Setelah langkah sebelum berjalan, permintaan diteruskan ke daftar fungsi. Fungsi pertama dalam daftar akan dijalankan terhadap sumber data. Fungsi adalah bagian dari kode resolver yang berisi request dan response handler sendiri. Penangan permintaan akan mengambil data permintaan dan melakukan operasi terhadap sumber data. Respon handler akan memproses respons sumber data sebelum meneruskannya kembali ke daftar. Jika ada lebih dari satu fungsi, data permintaan akan dikirim ke fungsi berikutnya dalam daftar yang akan dijalankan. Fungsi dalam daftar akan dijalankan secara serial dalam urutan yang ditentukan oleh pengembang. Setelah semua fungsi telah dijalankan, hasil akhir diteruskan ke langkah berikutnya.
-
Setelah langkah: Langkah setelah adalah fungsi handler yang memungkinkan Anda melakukan beberapa operasi akhir pada respons fungsi akhir sebelum meneruskannya ke respons GraphQL.
Struktur pengendali resolver
Handler biasanya merupakan fungsi yang disebut Request dan: Response
export function request(ctx) { // Code goes here } export function response(ctx) { // Code goes here }
Dalam unit resolver, hanya akan ada satu set fungsi ini. Dalam resolver pipeline, akan ada satu set ini untuk langkah sebelum dan sesudah dan satu set tambahan per fungsi. Untuk memvisualisasikan bagaimana ini bisa terlihat, mari kita tinjau Query tipe sederhana:
type Query { helloWorld: String! }
Ini adalah kueri sederhana dengan satu bidang yang disebut helloWorld tipeString. Mari kita asumsikan kita selalu ingin bidang ini mengembalikan string “Hello World”. Untuk menerapkan perilaku ini, kita perlu menambahkan resolver ke bidang ini. Dalam unit resolver, kita dapat menambahkan sesuatu seperti ini:
export function request(ctx) { return {} } export function response(ctx) { return "Hello World" }
Bisa request dibiarkan kosong karena kami tidak meminta atau memproses data. Kami juga dapat mengasumsikan sumber data kami adalahNone, menunjukkan kode ini tidak perlu melakukan pemanggilan apa pun. Jawabannya hanya mengembalikan “Hello World”. Untuk menguji resolver ini, kita perlu membuat permintaan menggunakan jenis kueri:
query helloWorldTest { helloWorld }
Ini adalah kueri helloWorldTest yang disebut yang mengembalikan helloWorld bidang. Saat dieksekusi, helloWorld field resolver juga mengeksekusi dan mengembalikan respons:
{ "data": { "helloWorld": "Hello World" } }
Mengembalikan konstanta seperti ini adalah hal paling sederhana yang dapat Anda lakukan. Pada kenyataannya, Anda akan mengembalikan input, daftar, dan banyak lagi. Berikut contoh yang lebih rumit:
type Book { id: ID! title: String } type Query { getBooks: [Book] }
Di sini kami mengembalikan daftarBooks. Mari kita asumsikan kita menggunakan tabel DynamoDB untuk menyimpan data buku. Handler kami mungkin terlihat seperti ini:
/** * 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; }
Permintaan kami menggunakan operasi pemindaian bawaan untuk mencari semua entri dalam tabel, menyimpan temuan dalam konteks, kemudian meneruskannya ke respons. Tanggapan mengambil item hasil dan mengembalikannya dalam tanggapan:
{ "data": { "getBooks": { "items": [ { "id": "abcdefgh-1234-1234-1234-abcdefghijkl", "title": "book1" }, { "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "title": "book2" }, ... ] } } }
Konteks resolver
Dalam resolver, setiap langkah dalam rantai penangan harus menyadari keadaan data dari langkah-langkah sebelumnya. Hasil dari satu handler dapat disimpan dan diteruskan ke yang lain sebagai argumen. GraphQL mendefinisikan empat argumen resolver dasar:
| Argumen dasar resolver | Deskripsi |
|---|---|
obj, root, parent, dll. |
Hasil dari orang tua. |
args |
Argumen yang diberikan ke bidang dalam kueri GraphQL. |
context |
Nilai yang diberikan kepada setiap resolver dan menyimpan informasi kontekstual penting seperti pengguna yang saat ini masuk, atau akses ke database. |
info |
Nilai yang menyimpan informasi khusus bidang yang relevan dengan kueri saat ini serta detail skema. |
Dalam AWS AppSync, argumen context (ctx) dapat menampung semua data yang disebutkan di atas. Ini adalah objek yang dibuat per permintaan dan berisi data seperti kredentif otorisasi, data hasil, kesalahan, metadata permintaan, dll. Konteks adalah cara mudah bagi programmer untuk memanipulasi data yang berasal dari bagian lain dari permintaan. Ambil cuplikan ini lagi:
/** * 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; }
Permintaan diberikan konteks (ctx) sebagai argumen; ini adalah status permintaan. Ini melakukan pemindaian untuk semua item dalam tabel, lalu menyimpan hasilnya kembali dalam konteks diresult. Konteks kemudian diteruskan ke argumen respons, yang mengakses result dan mengembalikan isinya.
Permintaan dan Penguraian
Ketika Anda membuat kueri ke layanan GraphQL Anda, itu harus dijalankan melalui proses penguraian dan validasi sebelum dieksekusi. Permintaan Anda akan diurai dan diterjemahkan ke dalam pohon sintaks abstrak. Isi pohon divalidasi dengan menjalankan beberapa algoritma validasi terhadap skema Anda. Setelah langkah validasi, simpul pohon dilintasi dan diproses. Resolver dipanggil, hasilnya disimpan dalam konteks, dan respons dikembalikan. Misalnya, ambil kueri ini:
query { Person { //object type name //scalar age //scalar } }
Kami kembali Person dengan ladang name danage. Saat menjalankan kueri ini, pohon akan terlihat seperti ini:
Dari pohon, tampaknya permintaan ini akan mencari akar untuk skema. Query Di dalam query, Person bidang akan diselesaikan. Dari contoh sebelumnya, kita tahu bahwa ini bisa menjadi input dari pengguna, daftar nilai, dll. Person Kemungkinan besar terkait dengan tipe objek yang menyimpan bidang yang kita butuhkan (namedanage). Setelah dua bidang anak ini ditemukan, mereka diselesaikan dalam urutan yang diberikan (namediikuti olehage). Setelah pohon benar-benar diselesaikan, permintaan selesai dan akan dikirim kembali ke klien.